Removed old work, this would be commit with just updates to TCP Client, and EventArgs.cs. After this adding back in classes for secure client and secure and unsecure server classes after this commit. Using the tested separated classes that were created for a project as dynamic modules.

This commit is contained in:
Joshua Gutenplan
2017-03-18 10:14:03 -07:00
parent 45049e415c
commit 6caff913ca
4 changed files with 0 additions and 1244 deletions

View File

@@ -1,501 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronSockets;
using PepperDash.Core;
namespace PepperDash.Core
{
public class DynamicTCPServer : Device
{
#region Events
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
public event EventHandler<DynamicTCPServerSocketStatusChangeEventArgs> ClientConnectionChange;
public event EventHandler<DynamicTCPServerStateChangedEventArgs> ServerStateChange;
#endregion
#region Properties/Variables
/// <summary>
/// Secure or unsecure TCP server. Defaults to Unsecure or standard TCP server without SSL
/// </summary>
public bool Secure { get; set; }
/// <summary>
/// S+ Helper for Secure bool. Parameter in SIMPL+ so there is no get, one way set from simpl+ Param to property in func main of SIMPL+
/// </summary>
public ushort uSecure
{
set
{
if (value == 1)
Secure = true;
else if (value == 0)
Secure = false;
}
}
public string status
{
get
{
if (Secure ? SecureServer != null : UnsecureServer != null)
return Secure ? SecureServer.State.ToString() : UnsecureServer.State.ToString();
else
return "";
}
}
/// <summary>
/// Bool showing if socket is connected
/// </summary>
public bool IsConnected
{
get { return (Secure ? SecureServer != null : UnsecureServer != null) &&
(Secure ? SecureServer.State == ServerState.SERVER_CONNECTED : UnsecureServer.State == ServerState.SERVER_CONNECTED); }
}
/// <summary>
/// S+ helper for IsConnected
/// </summary>
public ushort uIsConnected
{
get { return (ushort)(IsConnected ? 1 : 0); }
}
/// <summary>
/// Bool showing if socket is connected
/// </summary>
public bool IsListening
{
get { return (Secure ? SecureServer != null : UnsecureServer != null) &&
(Secure ? SecureServer.State == ServerState.SERVER_LISTENING : UnsecureServer.State == ServerState.SERVER_LISTENING); }
}
/// <summary>
/// S+ helper for IsConnected
/// </summary>
public ushort uIsListening
{
get { return (ushort)(IsListening ? 1 : 0); }
}
public ushort MaxClients { get; set; } // should be set by parameter in SIMPL+ in the MAIN method, Should not ever need to be configurable
/// <summary>
/// Number of clients currently connected.
/// </summary>
public ushort NumberOfClientsConnected
{
get
{
if (Secure ? SecureServer != null : UnsecureServer != null)
return Secure ? (ushort)SecureServer.NumberOfClientsConnected : (ushort)UnsecureServer.NumberOfClientsConnected;
return 0;
}
}
/// <summary>
/// Port on server
/// </summary>
public int Port { get; set; }
/// <summary>
/// S+ helper
/// </summary>
public ushort uPort
{
get { return Convert.ToUInt16(Port); }
set { Port = Convert.ToInt32(value); }
}
/// <summary>
/// Bool to show whether the server requires a preshared key. Must be set the same in the client, and if true shared keys must be identical on server/client
/// </summary>
public bool RequiresPresharedKey { get; set; }
/// <summary>
/// S+ helper for requires shared key bool
/// </summary>
public ushort uRequiresPresharedKey
{
set
{
if (value == 1)
RequiresPresharedKey = true;
else
RequiresPresharedKey = false;
}
}
/// <summary>
/// SharedKey is sent for varification to the server. Shared key can be any text (255 char limit in SIMPL+ Module), but must match the Shared Key on the Server module.
/// If SharedKey changes while server is listening or clients are connected, disconnect and stop listening will be called
/// </summary>
public string SharedKey { get; set; }
/// <summary>
/// flags to show the secure server is waiting for client at index to send the shared key
/// </summary>
public List<uint> WaitingForSharedKey = new List<uint>();
/// <summary>
/// Store the connected client indexes
/// </summary>
public List<uint> ConnectedClientsIndexes = new List<uint>();
/// <summary>
/// Defaults to 2000
/// </summary>
public int BufferSize { get; set; }
public string OnlyAcceptConnectionFromAddress { get; set; }
private bool ServerStopped { get; set; }
SecureTCPServer SecureServer;
TCPServer UnsecureServer;
#endregion
#region Constructors
//base class constructor
public DynamicTCPServer()
: base("Uninitialized Dynamic TCP Server")
{
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
BufferSize = 2000;
Secure = false;
}
#endregion
#region Methods - Server Actions
public void Initialize(string key)
{
Key = key;
}
public void Listen()
{
try
{
if (Port < 1 || Port > 65535)
{
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericSecureTcpClient '{0}': Invalid port", Key);
ErrorLog.Warn(string.Format("GenericSecureTcpClient '{0}': Invalid port", Key));
return;
}
if (string.IsNullOrEmpty(SharedKey) && RequiresPresharedKey)
{
Debug.Console(1, Debug.ErrorLogLevel.Warning, "GenericSecureTcpClient '{0}': No Shared Key set", Key);
ErrorLog.Warn(string.Format("GenericSecureTcpClient '{0}': No Shared Key set", Key));
return;
}
if (IsListening)
return;
if (Secure)
{
SecureServer = new SecureTCPServer(Port, MaxClients);
SecureServer.SocketStatusChange += new SecureTCPServerSocketStatusChangeEventHandler(SecureServer_SocketStatusChange);
ServerStopped = false;
if (!string.IsNullOrEmpty(OnlyAcceptConnectionFromAddress))
SecureServer.WaitForConnectionAsync(OnlyAcceptConnectionFromAddress, SecureConnectCallback);
else
SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
onServerStateChange();
Debug.Console(2, "Secure Server Status: {0}, Socket Status: {1}\r\n", SecureServer.State.ToString(), SecureServer.ServerSocketStatus);
}
else
{
UnsecureServer = new TCPServer(Port, MaxClients);
UnsecureServer.SocketStatusChange += new TCPServerSocketStatusChangeEventHandler(UnsecureServer_SocketStatusChange);
ServerStopped = false;
if (!string.IsNullOrEmpty(OnlyAcceptConnectionFromAddress))
UnsecureServer.WaitForConnectionAsync(OnlyAcceptConnectionFromAddress, UnsecureConnectCallback);
else
UnsecureServer.WaitForConnectionAsync(IPAddress.Any, UnsecureConnectCallback);
onServerStateChange();
Debug.Console(2, "Unsecure Server Status: {0}, Socket Status: {1}\r\n", UnsecureServer.State.ToString(), UnsecureServer.ServerSocketStatus);
}
}
catch (Exception ex)
{
ErrorLog.Error("Error with Dynamic Server: {0}", ex.ToString());
}
}
public void StopListening()
{
Debug.Console(2, "Stopping Listener");
if (SecureServer != null)
SecureServer.Stop();
if (UnsecureServer != null)
UnsecureServer.Stop();
ServerStopped = true;
onServerStateChange();
}
public void DisconnectAllClients()
{
Debug.Console(2, "Disconnecting All Clients");
if (SecureServer != null)
SecureServer.DisconnectAll();
if (UnsecureServer != null)
UnsecureServer.DisconnectAll();
onConnectionChange();
onServerStateChange(); //State shows both listening and connected
}
public void BroadcastText(string text)
{
if (ConnectedClientsIndexes.Count > 0)
{
if (Secure)
{
foreach (uint i in ConnectedClientsIndexes)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
SecureServer.SendDataAsync(i, b, b.Length, SecureSendDataAsyncCallback);
}
}
else
{
foreach (uint i in ConnectedClientsIndexes)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
UnsecureServer.SendDataAsync(i, b, b.Length, UnsecureSendDataAsyncCallback);
}
}
}
}
/// <summary>
/// Not sure this is useful in library, maybe Pro??
/// </summary>
/// <param name="text"></param>
/// <param name="clientIndex"></param>
public void SendTextToClient(string text, uint clientIndex)
{
if (Secure)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
SecureServer.SendDataAsync(clientIndex, b, b.Length, SecureSendDataAsyncCallback);
}
else
{
byte[] b = Encoding.GetEncoding(28591).GetBytes(text);
UnsecureServer.SendDataAsync(clientIndex, b, b.Length, UnsecureSendDataAsyncCallback);
}
}
#endregion
#region Methods - Socket Status Changed Callbacks
void SecureServer_SocketStatusChange(SecureTCPServer mySecureTCPServer, uint clientIndex, SocketStatus serverSocketStatus)
{
Debug.Console(2, "Client at {0} ServerSocketStatus {1}",
mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), serverSocketStatus.ToString());
if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
{
if (RequiresPresharedKey && !WaitingForSharedKey.Contains(clientIndex))
WaitingForSharedKey.Add(clientIndex);
if (!ConnectedClientsIndexes.Contains(clientIndex))
ConnectedClientsIndexes.Add(clientIndex);
}
if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) != SocketStatus.SOCKET_STATUS_CONNECTED && ConnectedClientsIndexes.Contains(clientIndex))
ConnectedClientsIndexes.Remove(clientIndex);
onConnectionChange();//Go to simpl and send the server and whether it is secure or not. Could check secure from Simpl+ but better to use the passed
//variable in case we need to use this in Pro. Simpl+ won't use arguments, will just check the uIsConnected Property. Currently Simpl+ is just going to report
//connected not reporting by client
}
void UnsecureServer_SocketStatusChange(TCPServer mySecureTCPServer, uint clientIndex, SocketStatus serverSocketStatus)
{
Debug.Console(2, "Client at {0} ServerSocketStatus {1}",
mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), serverSocketStatus.ToString());
if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
{
if (RequiresPresharedKey && !WaitingForSharedKey.Contains(clientIndex))
WaitingForSharedKey.Add(clientIndex);
if (!ConnectedClientsIndexes.Contains(clientIndex))
ConnectedClientsIndexes.Add(clientIndex);
}
if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) != SocketStatus.SOCKET_STATUS_CONNECTED && ConnectedClientsIndexes.Contains(clientIndex))
ConnectedClientsIndexes.Remove(clientIndex);
onConnectionChange();
}
#endregion
#region Methods Connected Callbacks
void SecureConnectCallback(SecureTCPServer mySecureTCPServer, uint clientIndex)
{
if (mySecureTCPServer.ClientConnected(clientIndex))
{
if (RequiresPresharedKey)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes(SharedKey + "\n");
mySecureTCPServer.SendDataAsync(clientIndex, b, b.Length, SecureSendDataAsyncCallback);
Debug.Console(2, "Sent Shared Key to client at {0}", mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
}
mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedCallback);
if (mySecureTCPServer.State != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped)
mySecureTCPServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback);
}
}
void UnsecureConnectCallback(TCPServer myTCPServer, uint clientIndex)
{
if (myTCPServer.ClientConnected(clientIndex))
{
if (RequiresPresharedKey)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes(SharedKey + "\n");
myTCPServer.SendDataAsync(clientIndex, b, b.Length, UnsecureSendDataAsyncCallback);
Debug.Console(2, "Sent Shared Key to client at {0}", myTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex));
}
myTCPServer.ReceiveDataAsync(clientIndex, UnsecureReceivedCallback);
if (myTCPServer.State != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped)
myTCPServer.WaitForConnectionAsync(IPAddress.Any, UnsecureConnectCallback);
}
if (myTCPServer.State != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped)
myTCPServer.WaitForConnectionAsync(IPAddress.Any, UnsecureConnectCallback);
}
#endregion
#region Methods - Send/Receive Callbacks
void SecureSendDataAsyncCallback(SecureTCPServer mySecureTCPServer, uint clientIndex, int numberOfBytesSent)
{
//Seems there is nothing to do here
}
void UnsecureSendDataAsyncCallback(TCPServer myTCPServer, uint clientIndex, int numberOfBytesSent)
{
//Seems there is nothing to do here
}
void SecureReceivedCallback(SecureTCPServer mySecureTCPServer, uint clientIndex, int numberOfBytesReceived)
{
if (numberOfBytesReceived > 0)
{
string received = "Nothing";
byte[] bytes = mySecureTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex);
received = System.Text.Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived);
if (WaitingForSharedKey.Contains(clientIndex))
{
received = received.Replace("\r", "");
received = received.Replace("\n", "");
if (received != SharedKey)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes("Shared key did not match server. Disconnecting");
Debug.Console(2, "Client at index {0} Shared key did not match the server, disconnecting client", clientIndex);
ErrorLog.Error("Client at index {0} Shared key did not match the server, disconnecting client", clientIndex);
mySecureTCPServer.SendDataAsync(clientIndex, b, b.Length, null);
mySecureTCPServer.Disconnect(clientIndex);
}
if (mySecureTCPServer.NumberOfClientsConnected > 0)
mySecureTCPServer.ReceiveDataAsync(SecureReceivedCallback);
WaitingForSharedKey.Remove(clientIndex);
byte[] skResponse = Encoding.GetEncoding(28591).GetBytes("Shared Key Match, Connected and ready for communication");
mySecureTCPServer.SendDataAsync(clientIndex, skResponse, skResponse.Length, null);
mySecureTCPServer.ReceiveDataAsync(SecureReceivedCallback);
}
else
{
mySecureTCPServer.ReceiveDataAsync(SecureReceivedCallback);
Debug.Console(2, "Secure Server Listening on Port: {0}, client IP: {1}, NumberOfBytesReceived: {2}, Received: {3}\r\n",
mySecureTCPServer.PortNumber, mySecureTCPServer.AddressServerAcceptedConnectionFrom, numberOfBytesReceived, received);
onTextReceived(received);
}
}
if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedCallback);
}
void UnsecureReceivedCallback(TCPServer myTCPServer, uint clientIndex, int numberOfBytesReceived)
{
if (numberOfBytesReceived > 0)
{
string received = "Nothing";
byte[] bytes = myTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex);
received = System.Text.Encoding.GetEncoding(28591).GetString(bytes, 0, numberOfBytesReceived);
if (WaitingForSharedKey.Contains(clientIndex))
{
received = received.Replace("\r", "");
received = received.Replace("\n", "");
if (received != SharedKey)
{
byte[] b = Encoding.GetEncoding(28591).GetBytes("Shared key did not match server. Disconnecting");
Debug.Console(2, "Client at index {0} Shared key did not match the server, disconnecting client", clientIndex);
ErrorLog.Error("Client at index {0} Shared key did not match the server, disconnecting client", clientIndex);
myTCPServer.SendDataAsync(clientIndex, b, b.Length, null);
myTCPServer.Disconnect(clientIndex);
}
if (myTCPServer.NumberOfClientsConnected > 0)
myTCPServer.ReceiveDataAsync(UnsecureReceivedCallback);
WaitingForSharedKey.Remove(clientIndex);
byte[] skResponse = Encoding.GetEncoding(28591).GetBytes("Shared Key Match, Connected and ready for communication");
myTCPServer.SendDataAsync(clientIndex, skResponse, skResponse.Length, null);
myTCPServer.ReceiveDataAsync(UnsecureReceivedCallback);
}
else
{
myTCPServer.ReceiveDataAsync(UnsecureReceivedCallback);
Debug.Console(2, "Secure Server Listening on Port: {0}, client IP: {1}, NumberOfBytesReceived: {2}, Received: {3}\r\n",
myTCPServer.PortNumber, myTCPServer.AddressServerAcceptedConnectionFrom, numberOfBytesReceived, received);
onTextReceived(received);
}
}
if (myTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED)
myTCPServer.ReceiveDataAsync(clientIndex, UnsecureReceivedCallback);
}
#endregion
#region Methods - EventHelpers/Callbacks
void onConnectionChange()
{
var handler = ClientConnectionChange;
if (handler != null)
{
if (Secure)
handler(this, new DynamicTCPServerSocketStatusChangeEventArgs(SecureServer, Secure));
else
handler(this, new DynamicTCPServerSocketStatusChangeEventArgs(UnsecureServer, Secure));
}
}
void onTextReceived(string text)
{
var handler = TextReceived;
if (handler != null)
handler(this, new GenericCommMethodReceiveTextArgs(text));
}
void onServerStateChange()
{
var handler = ServerStateChange;
if(handler != null)
{
if(Secure)
handler(this, new DynamicTCPServerStateChangedEventArgs(SecureServer, Secure));
else
handler(this, new DynamicTCPServerStateChangedEventArgs(UnsecureServer, Secure));
}
}
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{
if (programEventType == eProgramStatusEventType.Stopping)
{
Debug.Console(1, this, "Program stopping. Closing server");
DisconnectAllClients();
StopListening();
}
}
#endregion
}
}