diff --git a/Pepperdash Core/Pepperdash Core/Comm/._GenericSshClient.cs b/Pepperdash Core/Pepperdash Core/Comm/._GenericSshClient.cs new file mode 100644 index 0000000..583c583 Binary files /dev/null and b/Pepperdash Core/Pepperdash Core/Comm/._GenericSshClient.cs differ diff --git a/Pepperdash Core/Pepperdash Core/Comm/._GenericTcpIpClient.cs b/Pepperdash Core/Pepperdash Core/Comm/._GenericTcpIpClient.cs new file mode 100644 index 0000000..b65487e Binary files /dev/null and b/Pepperdash Core/Pepperdash Core/Comm/._GenericTcpIpClient.cs differ diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs index b61a39e..4ac42fa 100644 --- a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs +++ b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs @@ -65,11 +65,9 @@ namespace PepperDash.Core public bool IsConnected { // returns false if no client or not connected - get { return ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } + get { return Client != null && ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } } - private bool IsConnecting = false; - /// /// S+ helper for IsConnected /// @@ -134,10 +132,10 @@ namespace PepperDash.Core CTimer ReconnectTimer; - //string PreviousHostname; - //int PreviousPort; - //string PreviousUsername; - //string PreviousPassword; + //Lock object to prevent simulatneous connect/disconnect operations + private CCriticalSection connectLock = new CCriticalSection(); + + private bool DisconnectLogged = false; /// /// Typical constructor. @@ -153,6 +151,14 @@ namespace PepperDash.Core Username = username; Password = password; AutoReconnectIntervalMs = 5000; + + ReconnectTimer = new CTimer(o => + { + if (ConnectEnabled) + { + Connect(); + } + }, Timeout.Infinite); } /// @@ -161,9 +167,16 @@ namespace PepperDash.Core public GenericSshClient() : base(SPlusKey) { - StreamDebugging = new CommunicationStreamDebugging(SPlusKey); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); AutoReconnectIntervalMs = 5000; + + ReconnectTimer = new CTimer(o => + { + if (ConnectEnabled) + { + Connect(); + } + }, Timeout.Infinite); } /// @@ -194,115 +207,122 @@ namespace PepperDash.Core /// public void Connect() { - if (IsConnecting) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Connection attempt in progress. Exiting Connect()"); - return; - } - - IsConnecting = true; - ConnectEnabled = true; - Debug.Console(1, this, "attempting connect"); - - // Cancel reconnect if running. - if (ReconnectTimer != null) - { - ReconnectTimer.Stop(); - ReconnectTimer = null; - } - - // Don't try to connect if already - if (IsConnected) - return; - // Don't go unless everything is here if (string.IsNullOrEmpty(Hostname) || Port < 1 || Port > 65535 || Username == null || Password == null) { - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Connect failed. Check hostname, port, username and password are set or not null"); + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Connect failed. Check hostname, port, username and password are set or not null"); return; } - // Cleanup the old client if it already exists - if (Client != null) - { - Debug.Console(1, this, "Cleaning up disconnected client"); - Client.ErrorOccurred -= Client_ErrorOccurred; - KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY); - } + ConnectEnabled = true; - // This handles both password and keyboard-interactive (like on OS-X, 'nixes) - KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(Username); - kauth.AuthenticationPrompt += new EventHandler(kauth_AuthenticationPrompt); - PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(Username, Password); - - Debug.Console(1, this, "Creating new SshClient"); - ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth); - Client = new SshClient(connectionInfo); - - Client.ErrorOccurred -= Client_ErrorOccurred; - Client.ErrorOccurred += Client_ErrorOccurred; - - //Attempt to connect - ClientStatus = SocketStatus.SOCKET_STATUS_WAITING; try { - Client.Connect(); - TheStream = Client.CreateShellStream("PDTShell", 100, 80, 100, 200, 65534); - TheStream.DataReceived += Stream_DataReceived; - //TheStream.ErrorOccurred += TheStream_ErrorOccurred; - Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Connected"); - ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED; - IsConnecting = false; - return; // Success will not pass here - } - catch (SshConnectionException e) - { - var ie = e.InnerException; // The details are inside!! - if (ie is SocketException) - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "'{0}' CONNECTION failure: Cannot reach host, ({1})", Key, ie.Message); - else if (ie is System.Net.Sockets.SocketException) - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "'{0}' Connection failure: Cannot reach host '{1}' on port {2}, ({3})", - Key, Hostname, Port, ie.GetType()); - else if (ie is SshAuthenticationException) + connectLock.Enter(); + if (IsConnected) { - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Authentication failure for username '{0}', ({1})", - Username, ie.Message); + Debug.Console(1, this, "Connection already connected. Exiting Connect()"); } else - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Error on connect:\r({0})", e); + { + Debug.Console(1, this, "Attempting connect"); - ClientStatus = SocketStatus.SOCKET_STATUS_CONNECT_FAILED; - HandleConnectionFailure(); + // Cancel reconnect if running. + ReconnectTimer.Stop(); + + // Cleanup the old client if it already exists + if (Client != null) + { + Debug.Console(1, this, "Cleaning up disconnected client"); + KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY); + } + + // This handles both password and keyboard-interactive (like on OS-X, 'nixes) + KeyboardInteractiveAuthenticationMethod kauth = new KeyboardInteractiveAuthenticationMethod(Username); + kauth.AuthenticationPrompt += new EventHandler(kauth_AuthenticationPrompt); + PasswordAuthenticationMethod pauth = new PasswordAuthenticationMethod(Username, Password); + + Debug.Console(1, this, "Creating new SshClient"); + ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth); + Client = new SshClient(connectionInfo); + + Client.ErrorOccurred -= Client_ErrorOccurred; + Client.ErrorOccurred += Client_ErrorOccurred; + + //Attempt to connect + ClientStatus = SocketStatus.SOCKET_STATUS_WAITING; + try + { + Client.Connect(); + TheStream = Client.CreateShellStream("PDTShell", 100, 80, 100, 200, 65534); + TheStream.DataReceived += Stream_DataReceived; + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Connected"); + ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED; + DisconnectLogged = false; + } + catch (SshConnectionException e) + { + var ie = e.InnerException; // The details are inside!! + var errorLogLevel = DisconnectLogged == true ? Debug.ErrorLogLevel.None : Debug.ErrorLogLevel.Error; + + if (ie is SocketException) + Debug.Console(1, this, errorLogLevel, "'{0}' CONNECTION failure: Cannot reach host, ({1})", Key, ie.Message); + else if (ie is System.Net.Sockets.SocketException) + Debug.Console(1, this, errorLogLevel, "'{0}' Connection failure: Cannot reach host '{1}' on port {2}, ({3})", + Key, Hostname, Port, ie.GetType()); + else if (ie is SshAuthenticationException) + { + Debug.Console(1, this, errorLogLevel, "Authentication failure for username '{0}', ({1})", + Username, ie.Message); + } + else + Debug.Console(1, this, errorLogLevel, "Error on connect:\r({0})", ie.Message); + + DisconnectLogged = true; + KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED); + if (AutoReconnect) + { + Debug.Console(1, this, "Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs); + ReconnectTimer.Reset(AutoReconnectIntervalMs); + } + } + catch (Exception e) + { + var errorLogLevel = DisconnectLogged == true ? Debug.ErrorLogLevel.None : Debug.ErrorLogLevel.Error; + Debug.Console(1, this, errorLogLevel, "Unhandled exception on connect:\r({0})", e.Message); + DisconnectLogged = true; + KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED); + if (AutoReconnect) + { + Debug.Console(1, this, "Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs); + ReconnectTimer.Reset(AutoReconnectIntervalMs); + } + } + } } - catch (Exception e) + finally { - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Unhandled exception on connect:\r({0})", e); - ClientStatus = SocketStatus.SOCKET_STATUS_CONNECT_FAILED; - HandleConnectionFailure(); + connectLock.Leave(); } - - ClientStatus = SocketStatus.SOCKET_STATUS_CONNECT_FAILED; - HandleConnectionFailure(); } - - /// /// Disconnect the clients and put away it's resources. /// public void Disconnect() { - Debug.Console(2, "Disconnect Called"); - ConnectEnabled = false; - // Stop trying reconnects, if we are - if (ReconnectTimer != null) - { - ReconnectTimer.Stop(); - ReconnectTimer = null; - } - - KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY); + try + { + connectLock.Enter(); + // Stop trying reconnects, if we are + ReconnectTimer.Stop(); + KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY); + } + finally + { + connectLock.Leave(); + } } /// @@ -314,44 +334,21 @@ namespace PepperDash.Core IsConnecting = false; if (Client != null) { - Client.ErrorOccurred -= Client_ErrorOccurred; - Client.Disconnect(); - Client.Dispose(); - - Client = null; - ClientStatus = status; - Debug.Console(1, this, "Disconnected"); + try + { + Client.Disconnect(); + Client.Dispose(); + Client = null; + ClientStatus = status; + Debug.Console(1, this, "Disconnected client"); + } + catch (Exception ex) + { + Debug.Console(1, this, "Exception killing client: {0}", ex.Message); + } } } - /// - /// Anything to do with reestablishing connection on failures - /// - void HandleConnectionFailure() - { - KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED); - - Debug.Console(1, this, "Client nulled due to connection failure. AutoReconnect: {0}, ConnectEnabled: {1}", AutoReconnect, ConnectEnabled); - if (AutoReconnect && ConnectEnabled) - { - Debug.Console(1, this, "Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs); - if (ReconnectTimer == null) - { - ReconnectTimer = new CTimer(o => - { - Connect(); - }, AutoReconnectIntervalMs); - Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Attempting connection in {0} seconds", - (float) (AutoReconnectIntervalMs/1000)); - } - else - { - Debug.Console(1, this, "{0} second reconnect cycle running", - (float) (AutoReconnectIntervalMs/1000)); - } - } - } - /// /// Kills the stream /// @@ -363,6 +360,7 @@ namespace PepperDash.Core TheStream.Close(); TheStream.Dispose(); TheStream = null; + Debug.Console(1, this, "Disconnected stream"); } } @@ -413,13 +411,28 @@ namespace PepperDash.Core /// void Client_ErrorOccurred(object sender, Crestron.SimplSharp.Ssh.Common.ExceptionEventArgs e) { - if (e.Exception is SshConnectionException || e.Exception is System.Net.Sockets.SocketException) - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Disconnected by remote"); - else - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Unhandled SSH client error: {0}", e.Exception); + CrestronInvoke.BeginInvoke(o => + { + if (e.Exception is SshConnectionException || e.Exception is System.Net.Sockets.SocketException) + Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Disconnected by remote"); + else + Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Unhandled SSH client error: {0}", e.Exception); - ClientStatus = SocketStatus.SOCKET_STATUS_BROKEN_REMOTELY; - HandleConnectionFailure(); + try + { + connectLock.Enter(); + KillClient(SocketStatus.SOCKET_STATUS_BROKEN_REMOTELY); + } + finally + { + connectLock.Leave(); + } + if (AutoReconnect && ConnectEnabled) + { + Debug.Console(1, this, "Checking autoreconnect: {0}, {1}ms", AutoReconnect, AutoReconnectIntervalMs); + ReconnectTimer.Reset(AutoReconnectIntervalMs); + } + }); } /// @@ -461,8 +474,6 @@ namespace PepperDash.Core Debug.Console(0, "Stack Trace: {0}", ex.StackTrace); Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed. Disconnected, closing"); - ClientStatus = SocketStatus.SOCKET_STATUS_BROKEN_REMOTELY; - HandleConnectionFailure(); } } @@ -490,8 +501,6 @@ namespace PepperDash.Core catch { Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed. Disconnected, closing"); - ClientStatus = SocketStatus.SOCKET_STATUS_BROKEN_REMOTELY; - HandleConnectionFailure(); } } diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs index 16013a3..8cfaad2 100644 --- a/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs +++ b/Pepperdash Core/Pepperdash Core/Comm/GenericTcpIpClient.cs @@ -5,9 +5,7 @@ using System.Text; using System.Text.RegularExpressions; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronSockets; - using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace PepperDash.Core { @@ -39,23 +37,24 @@ namespace PepperDash.Core public event EventHandler ConnectionChange; - private string _Hostname { get; set;} + private string _hostname; + /// /// Address of server /// - public string Hostname { + public string Hostname + { get { - return _Hostname; + return _hostname; } set { - _Hostname = value; - if (Client != null) + _hostname = value; + if (_client != null) { - - Client.AddressClientConnectedTo = _Hostname; + _client.AddressClientConnectedTo = _hostname; } } } @@ -83,14 +82,14 @@ namespace PepperDash.Core /// /// The actual client class /// - public TCPClient Client { get; private set; } + private TCPClient _client; /// - /// True if connected to the server + /// Bool showing if socket is connected /// public bool IsConnected { - get { return Client != null && Client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } + get { return _client != null && _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } } /// @@ -102,21 +101,19 @@ namespace PepperDash.Core } /// - /// Status of the socket + /// _client socket status Read only /// public SocketStatus ClientStatus { get { - if (Client == null) - return SocketStatus.SOCKET_STATUS_NO_CONNECT; - return Client.ClientStatus; + return _client == null ? SocketStatus.SOCKET_STATUS_NO_CONNECT : _client.ClientStatus; } } /// /// Contains the familiar Simpl analog status values. This drives the ConnectionChange event - /// and IsConnected with be true when this == 2. + /// and IsConnected would be true when this == 2. /// public ushort UStatus { @@ -124,7 +121,7 @@ namespace PepperDash.Core } /// - /// Status of the socket + /// Status text shows the message associated with socket status /// public string ClientStatusText { get { return ClientStatus.ToString(); } } @@ -140,7 +137,7 @@ namespace PepperDash.Core public string ConnectionFailure { get { return ClientStatus.ToString(); } } /// - /// If true, enables AutoConnect + /// bool to track if auto reconnect should be set on the socket /// public bool AutoReconnect { get; set; } @@ -152,13 +149,14 @@ namespace PepperDash.Core get { return (ushort)(AutoReconnect ? 1 : 0); } set { AutoReconnect = value == 1; } } + /// /// Milliseconds to wait before attempting to reconnect. Defaults to 5000 /// public int AutoReconnectIntervalMs { get; set; } /// - /// Set only when the disconnect method is called. + /// Set only when the disconnect method is called /// bool DisconnectCalledByUser; @@ -167,10 +165,14 @@ namespace PepperDash.Core /// public bool Connected { - get { return Client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } + get { return _client.ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } } - CTimer RetryTimer; + //Lock object to prevent simulatneous connect/disconnect operations + private CCriticalSection connectLock = new CCriticalSection(); + + // private Timer for auto reconnect + private CTimer RetryTimer; /// /// Constructor @@ -183,13 +185,17 @@ namespace PepperDash.Core : base(key) { StreamDebugging = new CommunicationStreamDebugging(key); + CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); + AutoReconnectIntervalMs = 5000; Hostname = address; Port = port; BufferSize = bufferSize; - AutoReconnectIntervalMs = 5000; - CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); - } + RetryTimer = new CTimer(o => + { + Reconnect(); + }, Timeout.Infinite); + } /// /// Constructor @@ -202,6 +208,11 @@ namespace PepperDash.Core CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); AutoReconnectIntervalMs = 5000; BufferSize = 2000; + + RetryTimer = new CTimer(o => + { + Reconnect(); + }, Timeout.Infinite); } /// @@ -210,10 +221,14 @@ namespace PepperDash.Core public GenericTcpIpClient() : base(SplusKey) { - StreamDebugging = new CommunicationStreamDebugging(SplusKey); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); AutoReconnectIntervalMs = 5000; BufferSize = 2000; + + RetryTimer = new CTimer(o => + { + Reconnect(); + }, Timeout.Infinite); } /// @@ -232,7 +247,7 @@ namespace PepperDash.Core if (programEventType == eProgramStatusEventType.Stopping) { Debug.Console(1, this, "Program stopping. Closing connection"); - Disconnect(); + Deactivate(); } } @@ -242,9 +257,11 @@ namespace PepperDash.Core /// public override bool Deactivate() { - if (Client != null) + RetryTimer.Stop(); + RetryTimer.Dispose(); + if (_client != null) { - Client.SocketStatusChange -= this.Client_SocketStatusChange; + _client.SocketStatusChange -= this.Client_SocketStatusChange; DisconnectClient(); } return true; @@ -255,9 +272,6 @@ namespace PepperDash.Core /// public void Connect() { - if (IsConnected) - DisconnectClient(); - if (string.IsNullOrEmpty(Hostname)) { Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericTcpIpClient '{0}': No address set", Key); @@ -271,36 +285,72 @@ namespace PepperDash.Core } } - if (Client == null) + try { - Client = new TCPClient(Hostname, Port, BufferSize); - Client.SocketStatusChange -= Client_SocketStatusChange; - Client.SocketStatusChange += Client_SocketStatusChange; + connectLock.Enter(); + if (IsConnected) + { + Debug.Console(1, this, "Connection already connected. Exiting Connect()"); + } + else + { + //Stop retry timer if running + RetryTimer.Stop(); + _client = new TCPClient(Hostname, Port, BufferSize); + _client.SocketStatusChange -= Client_SocketStatusChange; + _client.SocketStatusChange += Client_SocketStatusChange; + DisconnectCalledByUser = false; + _client.ConnectToServerAsync(ConnectToServerCallback); + } + } + finally + { + connectLock.Leave(); } - DisconnectCalledByUser = false; - - Client.ConnectToServerAsync(ConnectToServerCallback); // (null); } + private void Reconnect() + { + if (_client == null) + { + return; + } + try + { + connectLock.Enter(); + if (IsConnected || DisconnectCalledByUser == true) + { + Debug.Console(1, this, "Reconnect no longer needed. Exiting Reconnect()"); + } + else + { + Debug.Console(1, this, "Attempting reconnect now"); + _client.ConnectToServerAsync(ConnectToServerCallback); + } + } + finally + { + connectLock.Leave(); + } + } + /// /// Attempts to disconnect the client /// public void Disconnect() { - DisconnectCalledByUser = true; - - // Stop trying reconnects, if we are - if (RetryTimer != null) + try { + connectLock.Enter(); + DisconnectCalledByUser = true; + + // Stop trying reconnects, if we are RetryTimer.Stop(); - RetryTimer = null; - } - - if (Client != null) - { DisconnectClient(); - Client = null; - Debug.Console(1, this, "Disconnected"); + } + finally + { + connectLock.Leave(); } } @@ -309,11 +359,11 @@ namespace PepperDash.Core /// public void DisconnectClient() { - if (Client != null) + if (_client != null) { Debug.Console(1, this, "Disconnecting client"); - if(IsConnected) - Client.DisconnectFromServer(); + if (IsConnected) + _client.DisconnectFromServer(); } } @@ -323,9 +373,15 @@ namespace PepperDash.Core /// void ConnectToServerCallback(TCPClient c) { - Debug.Console(1, this, "Server connection result: {0}", c.ClientStatus); - if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED && AutoReconnect) - WaitAndTryReconnect(); + if (c.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED) + { + Debug.Console(0, this, "Server connection result: {0}", c.ClientStatus); + WaitAndTryReconnect(); + } + else + { + Debug.Console(1, this, "Server connection result: {0}", c.ClientStatus); + } } /// @@ -333,24 +389,23 @@ namespace PepperDash.Core /// void WaitAndTryReconnect() { - DisconnectClient(); - - if (Client != null) + CrestronInvoke.BeginInvoke(o => { - Debug.Console(1, this, "Attempting reconnect, status={0}", Client.ClientStatus); - - if (!DisconnectCalledByUser) - RetryTimer = new CTimer(o => + try + { + connectLock.Enter(); + if (!IsConnected && AutoReconnect && !DisconnectCalledByUser && _client != null) { - if (Client == null) - { - return; - } - - Client.ConnectToServerAsync(ConnectToServerCallback); - }, AutoReconnectIntervalMs); - } - + DisconnectClient(); + Debug.Console(1, this, "Attempting reconnect, status={0}", _client.ClientStatus); + RetryTimer.Reset(AutoReconnectIntervalMs); + } + } + finally + { + connectLock.Leave(); + } + }); } /// @@ -380,15 +435,13 @@ namespace PepperDash.Core var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length); if (StreamDebugging.RxStreamDebuggingIsEnabled) + { Debug.Console(0, this, "Received {1} characters of text: '{0}'", ComTextHelper.GetDebugText(str), str.Length); + } textHandler(this, new GenericCommMethodReceiveTextArgs(str)); - - } - - + } } - client.ReceiveDataAsync(Receive); } } @@ -402,10 +455,8 @@ namespace PepperDash.Core // Check debug level before processing byte array if (StreamDebugging.TxStreamDebuggingIsEnabled) Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text)); - if(Client != null) - Client.SendData(bytes, bytes.Length); - - + if (_client != null) + _client.SendData(bytes, bytes.Length); } /// @@ -429,8 +480,8 @@ namespace PepperDash.Core { if (StreamDebugging.TxStreamDebuggingIsEnabled) Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes)); - if(Client != null) - Client.SendData(bytes, bytes.Length); + if (_client != null) + _client.SendData(bytes, bytes.Length); } /// @@ -440,27 +491,20 @@ namespace PepperDash.Core /// void Client_SocketStatusChange(TCPClient client, SocketStatus clientSocketStatus) { - Debug.Console(1, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText); - if (client.ClientStatus != SocketStatus.SOCKET_STATUS_CONNECTED && !DisconnectCalledByUser && AutoReconnect) - WaitAndTryReconnect(); - - // Probably doesn't need to be a switch since all other cases were eliminated - switch (clientSocketStatus) - { - case SocketStatus.SOCKET_STATUS_CONNECTED: - Client.ReceiveDataAsync(Receive); - DisconnectCalledByUser = false; - break; - } + if (clientSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) + { + Debug.Console(0, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText); + WaitAndTryReconnect(); + } + else + { + Debug.Console(1, this, "Socket status change {0} ({1})", clientSocketStatus, ClientStatusText); + _client.ReceiveDataAsync(Receive); + } var handler = ConnectionChange; if (handler != null) ConnectionChange(this, new GenericSocketStatusChageEventArgs(this)); - - // Relay the event - //var handler = SocketStatusChange; - //if (handler != null) - // SocketStatusChange(this); } } @@ -519,4 +563,4 @@ namespace PepperDash.Core } -} \ No newline at end of file +} diff --git a/Pepperdash Core/Pepperdash Core/Logging/Debug.cs b/Pepperdash Core/Pepperdash Core/Logging/Debug.cs index ee51b2c..1a84968 100644 --- a/Pepperdash Core/Pepperdash Core/Logging/Debug.cs +++ b/Pepperdash Core/Pepperdash Core/Logging/Debug.cs @@ -410,7 +410,10 @@ namespace PepperDash.Core string format, params object[] items) { var str = string.Format("[{0}] {1}", dev.Key, string.Format(format, items)); - LogError(errorLogLevel, str); + if (errorLogLevel != ErrorLogLevel.None) + { + LogError(errorLogLevel, str); + } if (Level >= level) { Console(level, str); @@ -424,7 +427,10 @@ namespace PepperDash.Core string format, params object[] items) { var str = string.Format(format, items); - LogError(errorLogLevel, str); + if (errorLogLevel != ErrorLogLevel.None) + { + LogError(errorLogLevel, str); + } if (Level >= level) { Console(level, str); @@ -566,6 +572,7 @@ namespace PepperDash.Core String.Format( @"Debug settings file migration not necessary. Using file at \user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber)); + return; }