merge development into release-2

This commit is contained in:
Andrew Welker
2025-03-03 17:09:34 -06:00
5 changed files with 533 additions and 448 deletions

View File

@@ -231,7 +231,10 @@ namespace PepperDash.Core
this.LogDebug("Attempting connect"); this.LogDebug("Attempting connect");
// Cancel reconnect if running. // Cancel reconnect if running.
ReconnectTimer.Stop(); if (ReconnectTimer != null)
{
ReconnectTimer.Stop();
}
// Cleanup the old client if it already exists // Cleanup the old client if it already exists
if (Client != null) if (Client != null)
@@ -248,8 +251,6 @@ namespace PepperDash.Core
this.LogDebug("Creating new SshClient"); this.LogDebug("Creating new SshClient");
ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth); ConnectionInfo connectionInfo = new ConnectionInfo(Hostname, Port, Username, pauth, kauth);
Client = new SshClient(connectionInfo); Client = new SshClient(connectionInfo);
Client.ErrorOccurred -= Client_ErrorOccurred;
Client.ErrorOccurred += Client_ErrorOccurred; Client.ErrorOccurred += Client_ErrorOccurred;
//Attempt to connect //Attempt to connect
@@ -258,6 +259,11 @@ namespace PepperDash.Core
{ {
Client.Connect(); Client.Connect();
TheStream = Client.CreateShellStream("PDTShell", 100, 80, 100, 200, 65534); TheStream = Client.CreateShellStream("PDTShell", 100, 80, 100, 200, 65534);
if (TheStream.DataAvailable)
{
// empty the buffer if there is data
string str = TheStream.Read();
}
TheStream.DataReceived += Stream_DataReceived; TheStream.DataReceived += Stream_DataReceived;
this.LogInformation("Connected"); this.LogInformation("Connected");
ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED; ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED;
@@ -336,7 +342,7 @@ namespace PepperDash.Core
if (ReconnectTimer != null) if (ReconnectTimer != null)
{ {
ReconnectTimer.Stop(); ReconnectTimer.Stop();
ReconnectTimer = null; // ReconnectTimer = null;
} }
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY); KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
@@ -349,28 +355,72 @@ namespace PepperDash.Core
{ {
KillStream(); KillStream();
if (Client != null) try
{ {
Client.Disconnect(); if (Client != null)
Client = null; {
ClientStatus = status; Client.ErrorOccurred -= Client_ErrorOccurred;
this.LogDebug("Disconnected"); Client.Disconnect();
Client.Dispose();
Client = null;
ClientStatus = status;
Debug.Console(1, this, "Disconnected");
}
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Exception in Kill Client:{0}", ex);
} }
} }
/// <summary>
/// Anything to do with reestablishing connection on failures
/// </summary>
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, "Attempting connection in {0} seconds",
(float) (AutoReconnectIntervalMs/1000));
}
else
{
Debug.Console(1, this, "{0} second reconnect cycle running",
(float) (AutoReconnectIntervalMs/1000));
}
}
}
/// <summary> /// <summary>
/// Kills the stream /// Kills the stream
/// </summary> /// </summary>
void KillStream() void KillStream()
{ {
if (TheStream != null) try
{ {
TheStream.DataReceived -= Stream_DataReceived; if (TheStream != null)
TheStream.Close(); {
TheStream.Dispose(); TheStream.DataReceived -= Stream_DataReceived;
TheStream = null; TheStream.Close();
this.LogDebug("Disconnected stream"); TheStream.Dispose();
} TheStream = null;
this.LogDebug("Disconnected stream");
}
}
catch (Exception ex)
{
this.LogException(ex, "Exception in Kill Stream:{0}");
}
} }
/// <summary> /// <summary>
@@ -388,29 +438,33 @@ namespace PepperDash.Core
/// </summary> /// </summary>
void Stream_DataReceived(object sender, ShellDataEventArgs e) void Stream_DataReceived(object sender, ShellDataEventArgs e)
{ {
var bytes = e.Data; if (((ShellStream)sender).Length <= 0L)
if (bytes.Length > 0) {
return;
}
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);
}
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived;
if (textHandler != null)
{ {
var bytesHandler = BytesReceived; if (StreamDebugging.RxStreamDebuggingIsEnabled)
if (bytesHandler != null) this.LogInformation("Received: '{0}'", ComTextHelper.GetDebugText(response));
{
if (StreamDebugging.RxStreamDebuggingIsEnabled)
{
this.LogInformation("Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
}
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived; textHandler(this, new GenericCommMethodReceiveTextArgs(response));
if (textHandler != null) }
{
var str = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
if (StreamDebugging.RxStreamDebuggingIsEnabled)
this.LogInformation("Received: '{0}'", ComTextHelper.GetDebugText(str));
textHandler(this, new GenericCommMethodReceiveTextArgs(str));
}
}
} }
@@ -460,22 +514,33 @@ namespace PepperDash.Core
/// <param name="text"></param> /// <param name="text"></param>
public void SendText(string text) public void SendText(string text)
{ {
try try
{ {
if (Client != null && TheStream != null && IsConnected) if (Client != null && TheStream != null && IsConnected)
{ {
if (StreamDebugging.TxStreamDebuggingIsEnabled) if (StreamDebugging.TxStreamDebuggingIsEnabled)
this.LogInformation("Sending {0} characters of text: '{1}'", text.Length, ComTextHelper.GetDebugText(text)); Debug.Console(0,
this,
"Sending {0} characters of text: '{1}'",
text.Length,
ComTextHelper.GetDebugText(text));
TheStream.Write(text); TheStream.Write(text);
TheStream.Flush(); TheStream.Flush();
}
else
{
Debug.Console(1, this, "Client is null or disconnected. Cannot Send Text");
}
}
catch (ObjectDisposedException ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Exception: {0}", ex.Message);
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Stack Trace: {0}", ex.StackTrace);
} KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
else ReconnectTimer.Reset();
{ }
this.LogDebug("Client is null or disconnected. Cannot Send Text");
}
}
catch (Exception ex) catch (Exception ex)
{ {
this.LogException(ex, "Exception sending text: {message}", text); this.LogException(ex, "Exception sending text: {message}", text);
@@ -503,10 +568,28 @@ namespace PepperDash.Core
this.LogDebug("Client is null or disconnected. Cannot Send Bytes"); this.LogDebug("Client is null or disconnected. Cannot Send Bytes");
} }
} }
catch (Exception ex) catch (ObjectDisposedException ex)
{ {
this.LogException(ex, "Exception sending bytes: {message}", ComTextHelper.GetEscapedText(bytes)); this.LogException(ex, "ObjectDisposedException sending {message}", ComTextHelper.GetEscapedText(bytes));
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
ReconnectTimer.Reset();
} }
catch (Exception ex)
{
this.LogException(ex, "Exception sending {message}", ComTextHelper.GetEscapedText(bytes));
}
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
ReconnectTimer.Reset();
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Exception: {0}", ex.Message);
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Stack Trace: {0}", ex.StackTrace);
Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stream write failed");
}
} }
#endregion #endregion

View File

@@ -219,7 +219,8 @@ namespace PepperDash.Core
/// </summary> /// </summary>
public GenericTcpIpClient() public GenericTcpIpClient()
: base(SplusKey) : base(SplusKey)
{ {
StreamDebugging = new CommunicationStreamDebugging(SplusKey);
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
AutoReconnectIntervalMs = 5000; AutoReconnectIntervalMs = 5000;
BufferSize = 2000; BufferSize = 2000;

View File

@@ -1,16 +1,17 @@
using Crestron.SimplSharp.WebScripting;
namespace PepperDash.Core.Web.RequestHandlers namespace PepperDash.Core.Web.RequestHandlers
{ {
/// <summary> /// <summary>
/// Web API default request handler /// Web API default request handler
/// </summary> /// </summary>
public class DefaultRequestHandler : WebApiBaseRequestHandler public class DefaultRequestHandler : WebApiBaseRequestHandler
{ {
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
public DefaultRequestHandler() public DefaultRequestHandler()
: base(true) : base(true)
{ } { }
} }
} }

View File

@@ -4,162 +4,162 @@ using Crestron.SimplSharp.WebScripting;
namespace PepperDash.Core.Web.RequestHandlers namespace PepperDash.Core.Web.RequestHandlers
{ {
/// <summary> /// <summary>
/// CWS Base Handler, implements IHttpCwsHandler /// CWS Base Handler, implements IHttpCwsHandler
/// </summary> /// </summary>
public abstract class WebApiBaseRequestHandler : IHttpCwsHandler public abstract class WebApiBaseRequestHandler : IHttpCwsHandler
{ {
private readonly Dictionary<string, Action<HttpCwsContext>> _handlers; private readonly Dictionary<string, Action<HttpCwsContext>> _handlers;
protected readonly bool EnableCors; protected readonly bool EnableCors;
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
protected WebApiBaseRequestHandler(bool enableCors) protected WebApiBaseRequestHandler(bool enableCors)
{ {
EnableCors = enableCors; EnableCors = enableCors;
_handlers = new Dictionary<string, Action<HttpCwsContext>> _handlers = new Dictionary<string, Action<HttpCwsContext>>
{ {
{"CONNECT", HandleConnect}, {"CONNECT", HandleConnect},
{"DELETE", HandleDelete}, {"DELETE", HandleDelete},
{"GET", HandleGet}, {"GET", HandleGet},
{"HEAD", HandleHead}, {"HEAD", HandleHead},
{"OPTIONS", HandleOptions}, {"OPTIONS", HandleOptions},
{"PATCH", HandlePatch}, {"PATCH", HandlePatch},
{"POST", HandlePost}, {"POST", HandlePost},
{"PUT", HandlePut}, {"PUT", HandlePut},
{"TRACE", HandleTrace} {"TRACE", HandleTrace}
}; };
} }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
protected WebApiBaseRequestHandler() protected WebApiBaseRequestHandler()
: this(false) : this(false)
{ {
} }
/// <summary> /// <summary>
/// Handles CONNECT method requests /// Handles CONNECT method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandleConnect(HttpCwsContext context) protected virtual void HandleConnect(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles DELETE method requests /// Handles DELETE method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandleDelete(HttpCwsContext context) protected virtual void HandleDelete(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles GET method requests /// Handles GET method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandleGet(HttpCwsContext context) protected virtual void HandleGet(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles HEAD method requests /// Handles HEAD method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandleHead(HttpCwsContext context) protected virtual void HandleHead(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles OPTIONS method requests /// Handles OPTIONS method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandleOptions(HttpCwsContext context) protected virtual void HandleOptions(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles PATCH method requests /// Handles PATCH method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandlePatch(HttpCwsContext context) protected virtual void HandlePatch(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles POST method requests /// Handles POST method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandlePost(HttpCwsContext context) protected virtual void HandlePost(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles PUT method requests /// Handles PUT method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandlePut(HttpCwsContext context) protected virtual void HandlePut(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Handles TRACE method requests /// Handles TRACE method requests
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void HandleTrace(HttpCwsContext context) protected virtual void HandleTrace(HttpCwsContext context)
{ {
context.Response.StatusCode = 501; context.Response.StatusCode = 501;
context.Response.StatusDescription = "Not Implemented"; context.Response.StatusDescription = "Not Implemented";
context.Response.End(); context.Response.End();
} }
/// <summary> /// <summary>
/// Process request /// Process request
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
public void ProcessRequest(HttpCwsContext context) public void ProcessRequest(HttpCwsContext context)
{ {
Action<HttpCwsContext> handler; Action<HttpCwsContext> handler;
if (!_handlers.TryGetValue(context.Request.HttpMethod, out handler)) if (!_handlers.TryGetValue(context.Request.HttpMethod, out handler))
{ {
return; return;
} }
if (EnableCors) if (EnableCors)
{ {
context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); context.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
} }
handler(context); handler(context);
} }
} }
} }

View File

@@ -9,276 +9,276 @@ using PepperDash.Core.Web.RequestHandlers;
namespace PepperDash.Core.Web namespace PepperDash.Core.Web
{ {
/// <summary> /// <summary>
/// Web API server /// Web API server
/// </summary> /// </summary>
public class WebApiServer : IKeyName public class WebApiServer : IKeyName
{ {
private const string SplusKey = "Uninitialized Web API Server"; private const string SplusKey = "Uninitialized Web API Server";
private const string DefaultName = "Web API Server"; private const string DefaultName = "Web API Server";
private const string DefaultBasePath = "/api"; private const string DefaultBasePath = "/api";
private const uint DebugTrace = 0; private const uint DebugTrace = 0;
private const uint DebugInfo = 1; private const uint DebugInfo = 1;
private const uint DebugVerbose = 2; private const uint DebugVerbose = 2;
private readonly CCriticalSection _serverLock = new CCriticalSection(); private readonly CCriticalSection _serverLock = new CCriticalSection();
private HttpCwsServer _server; private HttpCwsServer _server;
/// <summary> /// <summary>
/// Web API server key /// Web API server key
/// </summary> /// </summary>
public string Key { get; private set; } public string Key { get; private set; }
/// <summary> /// <summary>
/// Web API server name /// Web API server name
/// </summary> /// </summary>
public string Name { get; private set; } public string Name { get; private set; }
/// <summary> /// <summary>
/// CWS base path, will default to "/api" if not set via initialize method /// CWS base path, will default to "/api" if not set via initialize method
/// </summary> /// </summary>
public string BasePath { get; private set; } public string BasePath { get; private set; }
/// <summary> /// <summary>
/// Indicates CWS is registered with base path /// Indicates CWS is registered with base path
/// </summary> /// </summary>
public bool IsRegistered { get; private set; } public bool IsRegistered { get; private set; }
/// <summary> /// <summary>
/// Http request handler /// Http request handler
/// </summary> /// </summary>
//public IHttpCwsHandler HttpRequestHandler //public IHttpCwsHandler HttpRequestHandler
//{ //{
// get { return _server.HttpRequestHandler; } // get { return _server.HttpRequestHandler; }
// set // set
// { // {
// if (_server == null) return; // if (_server == null) return;
// _server.HttpRequestHandler = value; // _server.HttpRequestHandler = value;
// } // }
//} //}
/// <summary> /// <summary>
/// Received request event handler /// Received request event handler
/// </summary> /// </summary>
//public event EventHandler<HttpCwsRequestEventArgs> ReceivedRequestEvent //public event EventHandler<HttpCwsRequestEventArgs> ReceivedRequestEvent
//{ //{
// add { _server.ReceivedRequestEvent += new HttpCwsRequestEventHandler(value); } // add { _server.ReceivedRequestEvent += new HttpCwsRequestEventHandler(value); }
// remove { _server.ReceivedRequestEvent -= new HttpCwsRequestEventHandler(value); } // remove { _server.ReceivedRequestEvent -= new HttpCwsRequestEventHandler(value); }
//} //}
/// <summary> /// <summary>
/// Constructor for S+. Make sure to set necessary properties using init method /// Constructor for S+. Make sure to set necessary properties using init method
/// </summary> /// </summary>
public WebApiServer() public WebApiServer()
: this(SplusKey, DefaultName, null) : this(SplusKey, DefaultName, null)
{ {
} }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="basePath"></param> /// <param name="basePath"></param>
public WebApiServer(string key, string basePath) public WebApiServer(string key, string basePath)
: this(key, DefaultName, basePath) : this(key, DefaultName, basePath)
{ {
} }
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="basePath"></param> /// <param name="basePath"></param>
public WebApiServer(string key, string name, string basePath) public WebApiServer(string key, string name, string basePath)
{ {
Key = key; Key = key;
Name = string.IsNullOrEmpty(name) ? DefaultName : name; Name = string.IsNullOrEmpty(name) ? DefaultName : name;
BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath; BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath;
if (_server == null) _server = new HttpCwsServer(BasePath); if (_server == null) _server = new HttpCwsServer(BasePath);
_server.setProcessName(Key); _server.setProcessName(Key);
_server.HttpRequestHandler = new DefaultRequestHandler(); _server.HttpRequestHandler = new DefaultRequestHandler();
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
} }
/// <summary> /// <summary>
/// Program status event handler /// Program status event handler
/// </summary> /// </summary>
/// <param name="programEventType"></param> /// <param name="programEventType"></param>
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{ {
if (programEventType != eProgramStatusEventType.Stopping) return; if (programEventType != eProgramStatusEventType.Stopping) return;
Debug.Console(DebugInfo, this, "Program stopping. stopping server"); Debug.Console(DebugInfo, this, "Program stopping. stopping server");
Stop(); Stop();
} }
/// <summary> /// <summary>
/// Ethernet event handler /// Ethernet event handler
/// </summary> /// </summary>
/// <param name="ethernetEventArgs"></param> /// <param name="ethernetEventArgs"></param>
void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs) void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs)
{ {
// Re-enable the server if the link comes back up and the status should be connected // Re-enable the server if the link comes back up and the status should be connected
if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp && IsRegistered) if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp && IsRegistered)
{ {
Debug.Console(DebugInfo, this, "Ethernet link up. Server is alreedy registered."); Debug.Console(DebugInfo, this, "Ethernet link up. Server is alreedy registered.");
return; return;
} }
Debug.Console(DebugInfo, this, "Ethernet link up. Starting server"); Debug.Console(DebugInfo, this, "Ethernet link up. Starting server");
Start(); Start();
} }
/// <summary> /// <summary>
/// Initializes CWS class /// Initializes CWS class
/// </summary> /// </summary>
public void Initialize(string key, string basePath) public void Initialize(string key, string basePath)
{ {
Key = key; Key = key;
BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath; BasePath = string.IsNullOrEmpty(basePath) ? DefaultBasePath : basePath;
} }
/// <summary> /// <summary>
/// Adds a route to CWS /// Adds a route to CWS
/// </summary> /// </summary>
public void AddRoute(HttpCwsRoute route) public void AddRoute(HttpCwsRoute route)
{ {
if (route == null) if (route == null)
{ {
Debug.Console(DebugInfo, this, "Failed to add route, route parameter is null"); Debug.Console(DebugInfo, this, "Failed to add route, route parameter is null");
return; return;
} }
_server.Routes.Add(route); _server.Routes.Add(route);
} }
/// <summary> /// <summary>
/// Removes a route from CWS /// Removes a route from CWS
/// </summary> /// </summary>
/// <param name="route"></param> /// <param name="route"></param>
public void RemoveRoute(HttpCwsRoute route) public void RemoveRoute(HttpCwsRoute route)
{ {
if (route == null) if (route == null)
{ {
Debug.Console(DebugInfo, this, "Failed to remote route, orute parameter is null"); Debug.Console(DebugInfo, this, "Failed to remote route, orute parameter is null");
return; return;
} }
_server.Routes.Remove(route); _server.Routes.Remove(route);
} }
/// <summary> /// <summary>
/// Returns a list of the current routes /// Returns a list of the current routes
/// </summary> /// </summary>
public HttpCwsRouteCollection GetRouteCollection() public HttpCwsRouteCollection GetRouteCollection()
{ {
return _server.Routes; return _server.Routes;
} }
/// <summary> /// <summary>
/// Starts CWS instance /// Starts CWS instance
/// </summary> /// </summary>
public void Start() public void Start()
{ {
try try
{ {
_serverLock.Enter(); _serverLock.Enter();
if (_server == null) if (_server == null)
{ {
Debug.Console(DebugInfo, this, "Server is null, unable to start"); Debug.Console(DebugInfo, this, "Server is null, unable to start");
return; return;
} }
if (IsRegistered) if (IsRegistered)
{ {
Debug.Console(DebugInfo, this, "Server has already been started"); Debug.Console(DebugInfo, this, "Server has already been started");
return; return;
} }
IsRegistered = _server.Register(); IsRegistered = _server.Register();
Debug.Console(DebugInfo, this, "Starting server, registration {0}", IsRegistered ? "was successful" : "failed"); Debug.Console(DebugInfo, this, "Starting server, registration {0}", IsRegistered ? "was successful" : "failed");
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(DebugInfo, this, "Start Exception Message: {0}", ex.Message); Debug.Console(DebugInfo, this, "Start Exception Message: {0}", ex.Message);
Debug.Console(DebugVerbose, this, "Start Exception StackTrace: {0}", ex.StackTrace); Debug.Console(DebugVerbose, this, "Start Exception StackTrace: {0}", ex.StackTrace);
if (ex.InnerException != null) if (ex.InnerException != null)
Debug.Console(DebugVerbose, this, "Start Exception InnerException: {0}", ex.InnerException); Debug.Console(DebugVerbose, this, "Start Exception InnerException: {0}", ex.InnerException);
} }
finally finally
{ {
_serverLock.Leave(); _serverLock.Leave();
} }
} }
/// <summary> /// <summary>
/// Stop CWS instance /// Stop CWS instance
/// </summary> /// </summary>
public void Stop() public void Stop()
{ {
try try
{ {
_serverLock.Enter(); _serverLock.Enter();
if (_server == null) if (_server == null)
{ {
Debug.Console(DebugInfo, this, "Server is null or has already been stopped"); Debug.Console(DebugInfo, this, "Server is null or has already been stopped");
return; return;
} }
IsRegistered = _server.Unregister() == false; IsRegistered = _server.Unregister() == false;
Debug.Console(DebugInfo, this, "Stopping server, unregistration {0}", IsRegistered ? "failed" : "was successful"); Debug.Console(DebugInfo, this, "Stopping server, unregistration {0}", IsRegistered ? "failed" : "was successful");
_server.Dispose(); _server.Dispose();
_server = null; _server = null;
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(DebugInfo, this, "Server Stop Exception Message: {0}", ex.Message); Debug.Console(DebugInfo, this, "Server Stop Exception Message: {0}", ex.Message);
Debug.Console(DebugVerbose, this, "Server Stop Exception StackTrace: {0}", ex.StackTrace); Debug.Console(DebugVerbose, this, "Server Stop Exception StackTrace: {0}", ex.StackTrace);
if (ex.InnerException != null) if (ex.InnerException != null)
Debug.Console(DebugVerbose, this, "Server Stop Exception InnerException: {0}", ex.InnerException); Debug.Console(DebugVerbose, this, "Server Stop Exception InnerException: {0}", ex.InnerException);
} }
finally finally
{ {
_serverLock.Leave(); _serverLock.Leave();
} }
} }
/// <summary> /// <summary>
/// Received request handler /// Received request handler
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This is here for development and testing /// This is here for development and testing
/// </remarks> /// </remarks>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="args"></param> /// <param name="args"></param>
public void ReceivedRequestEventHandler(object sender, HttpCwsRequestEventArgs args) public void ReceivedRequestEventHandler(object sender, HttpCwsRequestEventArgs args)
{ {
try try
{ {
var j = JsonConvert.SerializeObject(args.Context, Formatting.Indented); var j = JsonConvert.SerializeObject(args.Context, Formatting.Indented);
Debug.Console(DebugVerbose, this, "RecieveRequestEventHandler Context:\x0d\x0a{0}", j); Debug.Console(DebugVerbose, this, "RecieveRequestEventHandler Context:\x0d\x0a{0}", j);
} }
catch (Exception ex) catch (Exception ex)
{ {
Debug.Console(DebugInfo, this, "ReceivedRequestEventHandler Exception Message: {0}", ex.Message); Debug.Console(DebugInfo, this, "ReceivedRequestEventHandler Exception Message: {0}", ex.Message);
Debug.Console(DebugVerbose, this, "ReceivedRequestEventHandler Exception StackTrace: {0}", ex.StackTrace); Debug.Console(DebugVerbose, this, "ReceivedRequestEventHandler Exception StackTrace: {0}", ex.StackTrace);
if (ex.InnerException != null) if (ex.InnerException != null)
Debug.Console(DebugVerbose, this, "ReceivedRequestEventHandler Exception InnerException: {0}", ex.InnerException); Debug.Console(DebugVerbose, this, "ReceivedRequestEventHandler Exception InnerException: {0}", ex.InnerException);
} }
} }
} }
} }