/// <summary> /// Secure Server Socket Status Changed Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="serverSocketStatus"></param> void SecureServer_SocketStatusChange(SecureTCPServer server, uint clientIndex, SocketStatus serverSocketStatus) { Debug.Console(2, "Client at {0} ServerSocketStatus {1}", server.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), serverSocketStatus.ToString()); if (server.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) { if (SharedKeyRequired && !WaitingForSharedKey.Contains(clientIndex)) { WaitingForSharedKey.Add(clientIndex); } if (!ConnectedClientsIndexes.Contains(clientIndex)) { ConnectedClientsIndexes.Add(clientIndex); } } else { if (ConnectedClientsIndexes.Contains(clientIndex)) { ConnectedClientsIndexes.Remove(clientIndex); } if (HeartbeatRequired && HeartbeatTimerDictionary.ContainsKey(clientIndex)) { HeartbeatTimerDictionary.Remove(clientIndex); } } if (SecureServer.ServerSocketStatus.ToString() != Status) { onConnectionChange(); } }
override protected void ReceiveCallback(SecureTCPServer server, uint clientIndex, int numberOfBytesReceived) { try { if (numberOfBytesReceived > 0 && server.GetIncomingDataBufferForSpecificClient(clientIndex) != null) { byte[] data = new byte[numberOfBytesReceived]; Array.Copy(server.GetIncomingDataBufferForSpecificClient(clientIndex), data, numberOfBytesReceived); server.ReceiveDataAsync(clientIndex, ReceiveCallback); //PrintFrameStatus(data); if (((data[0] & 0x0F) == 0x09)) { CrestronLogger.WriteToLog("WS_SERVER Receive callback PING DETECTED", 9); SendPongToWebSocketClient(data, clientIndex); } else if (((data[0] & 0x0F) == 0x08)) { CrestronLogger.WriteToLog("WS_SERVER - Receive callback - CONNECTION CLOSE PACKET RECEIVED, CLOSING...", 9); Send(clientIndex, data); DisconnectClient(clientIndex, true); } else { ParseFrame(clientIndex, data); } } } catch (Exception e) { CrestronLogger.WriteToLog("WS_SERVER - Exception occured : " + e.Message + " " + e.InnerException + " " + e.StackTrace, 9); DisconnectClient(clientIndex, false); } }
override protected void ConnectionCallback(SecureTCPServer server, uint clientIndex) { try { Server.WaitForConnectionAsync(IPAddress.Parse("0.0.0.0"), this.ConnectionCallback); if (Server.ClientConnected(clientIndex)) { oldDecodedFrame.Add(clientIndex, new List <byte>()); int lenghtOfData = Server.ReceiveData(clientIndex); byte[] data = Server.GetIncomingDataBufferForSpecificClient(clientIndex); MqttMsgBase packet = PacketDecoder.DecodeControlPacket(data); if (packet.Type == MqttMsgBase.MQTT_MSG_CONNECT_TYPE) { OnPacketReceived(clientIndex, packet, false); } else { throw new ArgumentException("Attempted connection with a non CONNECT packet"); } } } catch (Exception e) { DisconnectClient(clientIndex, false); } }
private void ConnectionDataCallback(SecureTCPServer server, uint clientIndex, int numberOfBytesReceived) { try { byte[] data = server.GetIncomingDataBufferForSpecificClient(clientIndex); string dataASCIIEncoded = Encoding.ASCII.GetString(data, 0, data.Length); //TODO: Cambiare la regex e renderla sicura if (new Regex("^GET").IsMatch(dataASCIIEncoded)) { CrestronLogger.WriteToLog("WS_SERVER - PERFORMING HANDSHAKE", 1); PerformHandShake(clientIndex, dataASCIIEncoded); if (server.ClientConnected(clientIndex)) { oldDecodedFrame.Add(clientIndex, new List <byte>()); server.ReceiveDataAsync(clientIndex, ReceiveCallback); } } else { RejectConnection(clientIndex); } } catch (Exception) { CrestronLogger.WriteToLog("WS_SERVER - ConnectionCallback - connection error ", 8); RejectConnection(clientIndex); } }
public void ServerDataReceivedCallback(SecureTCPServer server, uint clientIndex, int bytesReceived) { if (bytesReceived <= 0) { CrestronConsole.PrintLine("ServerDataReceivedCallback error: server's connection with client " + clientIndex + " has been closed."); server.Disconnect(clientIndex); // A connection has closed, so another client may connect if the server stopped listening // due to the maximum number of clients connecting if ((server.State & ServerState.SERVER_NOT_LISTENING) > 0) { server.WaitForConnectionAsync(ServerConnectedCallback); } } else { CrestronConsole.PrintLine("\n------ incoming message -----------"); byte[] recvd_bytes = new byte[bytesReceived]; // Copy the received bytes into a local buffer so that they can be echoed back. // Do not pass the reference to the incoming data buffer itself to the SendDataAsync method Array.Copy(server.GetIncomingDataBufferForSpecificClient(clientIndex), recvd_bytes, bytesReceived); // The server in this example expects ASCII text from the client, but any other encoding is possible string recvd_msg = ASCIIEncoding.ASCII.GetString(recvd_bytes, 0, bytesReceived); CrestronConsole.PrintLine("Client " + clientIndex + " says: " + recvd_msg + "\r\nEchoing back to client " + clientIndex + "..."); // echo the received message back to the client who sent it server.SendDataAsync(clientIndex, recvd_bytes, recvd_bytes.Length, ServerDataSentCallback); // Begin waiting for another message from that same client server.ReceiveDataAsync(clientIndex, ServerDataReceivedCallback); CrestronConsole.PrintLine("---------- end of message ----------"); } }
public SecureServer() { CrestronConsole.AddNewConsoleCommand(Listen, "listen", "usage: listen [<cert_file> <key_file>] <port>", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(Disconnect, "disconnect", "usage: disconnect [<client_index>]", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ShowStatus, "showstatus", "usage: showstatus [<client_index>]", ConsoleAccessLevelEnum.AccessOperator); server = null; }
public void Disconnect(string args) { try { if (server == null) { CrestronConsole.PrintLine("Server is already disconnected"); return; } if (args == "") { // When no arguments are provided, disconnect from all clients and destroy the server server.DisconnectAll(); CrestronConsole.PrintLine("Server has disconnected from all clients and is no longer listening on port " + server.PortNumber); server = null; } else { // Disconnect from the client specified by the user uint clientIndex = uint.Parse(args); if (server.ClientConnected(clientIndex)) { server.Disconnect(clientIndex); CrestronConsole.PrintLine("Server has disconnected from " + clientIndex); } else { CrestronConsole.PrintLine("Client #" + clientIndex + " does not exist currently"); } } } catch (Exception e) { PrintAndLog("Error in Disconnect: " + e.Message); } }
protected void OnSocketStatusChange(SecureTCPServer myTCPServer, uint clientIndex, SocketStatus serverSocketStatus) { if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) { DisconnectClient(clientIndex, false); } }
protected void OnSocketStatusChange(SecureTCPServer myTCPServer, uint clientIndex, SocketStatus serverSocketStatus) { if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) { CrestronConsole.PrintLine("Socket Status Change Disconnecting!"); DisconnectClient(clientIndex, false); } }
/// <summary> /// Start listening on the specified port /// </summary> public void Listen() { ServerCCSection.Enter(); try { if (Port < 1 || Port > 65535) { Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Server '{0}': Invalid port", Key); ErrorLog.Warn(string.Format("Server '{0}': Invalid port", Key)); return; } if (string.IsNullOrEmpty(SharedKey) && SharedKeyRequired) { Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Server '{0}': No Shared Key set", Key); ErrorLog.Warn(string.Format("Server '{0}': No Shared Key set", Key)); return; } if (SecureServer == null) { SecureServer = new SecureTCPServer(Port, MaxClients); if (HeartbeatRequired) { SecureServer.SocketSendOrReceiveTimeOutInMs = (this.HeartbeatRequiredIntervalMs * 5); } SecureServer.HandshakeTimeout = 30; SecureServer.SocketStatusChange += new SecureTCPServerSocketStatusChangeEventHandler(SecureServer_SocketStatusChange); } else { SecureServer.PortNumber = Port; } ServerStopped = false; // 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) { ServerCCSection.Leave(); ErrorLog.Error("{1} Error with Dynamic Server: {0}", ex.ToString(), Key); } }
public void ServerDataSentCallback(SecureTCPServer server, uint clientIndex, int bytesSent) { if (bytesSent <= 0) { CrestronConsole.PrintLine("Error sending message. Connection has been closed"); } else { CrestronConsole.PrintLine("Echoed message to client " + clientIndex + " (" + bytesSent + " byte(s))"); } }
public ServerBase(List <MqttClient> clients, SessionManager sessionManager, List <ushort> packetIdentifiers, Random rand, int port, int numberOfConnections) { Clients = clients; SessionManager = sessionManager; PacketIdentifiers = packetIdentifiers; Rand = rand; this.Port = port; this.NumberOfConnections = numberOfConnections; Server = new SecureTCPServer(port, 4096, EthernetAdapterType.EthernetLANAdapter, numberOfConnections); Server.SocketStatusChange += OnSocketStatusChange; Server.WaitForConnectionAsync(IPAddress.Parse("0.0.0.0"), this.ConnectionCallback); }
/// <summary> /// The client connection callback for the secure server. /// </summary> /// <param name="server">The server the callback is executed on.</param> /// <param name="clientIndex">The index of the connecting client.</param> private void SecureClientConnectionCallback(SecureTCPServer server, uint clientIndex) { if (clientIndex > 0) { CrestronConsole.PrintLine("Client connected at index '{0}'.", clientIndex); if (!connectedSocketIndexes.Contains(clientIndex)) { connectedSocketIndexes.Add(clientIndex); } server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback); } }
public void ServerSocketStatusChanged(SecureTCPServer server, uint clientIndex, SocketStatus status) { // A single SecureTCPServer may be handling many different sockets (up to server.MaxNumberOfClientSupported) at once. // This event handler is called whenever the status of any one of these sockets changes. clientIndex // uniquely identifies which socket has received a new status. if (status == SocketStatus.SOCKET_STATUS_CONNECTED) { CrestronConsole.PrintLine("ServerSocketStatusChanged: Client " + clientIndex + " connected."); } else { CrestronConsole.PrintLine("ServerSocketStatusChange for client " + clientIndex + ": " + status + "."); } }
/// <summary> /// Disposes of resources. /// </summary> public void Dispose() { if (tcpServer != null) { tcpServer.Stop(); tcpServer.DisconnectAll(); tcpServer = null; } if (secureTcpServer != null) { secureTcpServer.Stop(); secureTcpServer.DisconnectAll(); secureTcpServer = null; } }
override protected void ConnectionCallback(SecureTCPServer server, uint clientIndex) { try { Server.WaitForConnectionAsync(IPAddress.Parse("0.0.0.0"), this.ConnectionCallback); if (Server.ClientConnected(clientIndex)) { oldDecodedFrame.Add(clientIndex, new List <byte>()); server.ReceiveDataAsync(clientIndex, ReceiveCallback); } } catch (Exception e) { DisconnectClient(clientIndex, false); } }
/// <summary> /// Handles socket status changes for the secure server. /// </summary> /// <param name="server">The server that had a socket change event.</param> /// <param name="clientIndex">The index of the client who's socket connection changed.</param> /// <param name="serverSocketStatus">The new socket status.</param> private void SecureSocketStatusChange(SecureTCPServer server, uint clientIndex, SocketStatus serverSocketStatus) { if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) { connectedSocketIndexes.Remove(clientIndex); } if (serverSocketStatus == SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY || serverSocketStatus == SocketStatus.SOCKET_STATUS_BROKEN_REMOTELY) { if (startRequested) { server.WaitForConnectionsAlways(SecureClientConnectionCallback); } } }
/// <summary> /// Starts the secure server. /// </summary> /// <param name="port">The port the server should be started on.</param> private void StartSecureServer(int port) { if (secureTcpServer != null) { secureTcpServer.SocketStatusChange -= SecureSocketStatusChange; secureTcpServer.DisconnectAll(); connectedSocketIndexes.Clear(); secureTcpServer = null; } CrestronConsole.PrintLine("Starting secure server."); secureTcpServer = new SecureTCPServer(IPAddress.Any.ToString(), port, 1024, EthernetAdapterType.EthernetUnknownAdapter, 10); secureTcpServer.SocketStatusChange += SecureSocketStatusChange; secureTcpServer.WaitForConnectionsAlways(SecureClientConnectionCallback); }
/// <summary> /// Start listening on the specified port /// </summary> 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) && SharedKeyRequired) { 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; 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; 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()); } }
/// <summary> /// Secure Server Socket Status Changed Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="serverSocketStatus"></param> void SecureServer_SocketStatusChange(SecureTCPServer server, uint clientIndex, SocketStatus serverSocketStatus) { try { // Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange Index:{0} status:{1} Port:{2} IP:{3}", clientIndex, serverSocketStatus, this.SecureServer.GetPortNumberServerAcceptedConnectionFromForSpecificClient(clientIndex), this.SecureServer.GetLocalAddressServerAcceptedConnectionFromForSpecificClient(clientIndex)); if (serverSocketStatus != SocketStatus.SOCKET_STATUS_CONNECTED) { Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SecureServerSocketStatusChange ConnectedCLients: {0} ServerState: {1} Port: {2}", SecureServer.NumberOfClientsConnected, SecureServer.State, SecureServer.PortNumber); if (ConnectedClientsIndexes.Contains(clientIndex)) { ConnectedClientsIndexes.Remove(clientIndex); } if (HeartbeatRequired && HeartbeatTimerDictionary.ContainsKey(clientIndex)) { HeartbeatTimerDictionary[clientIndex].Stop(); HeartbeatTimerDictionary[clientIndex].Dispose(); HeartbeatTimerDictionary.Remove(clientIndex); } if (ClientReadyAfterKeyExchange.Contains(clientIndex)) { ClientReadyAfterKeyExchange.Remove(clientIndex); } if (WaitingForSharedKey.Contains(clientIndex)) { WaitingForSharedKey.Remove(clientIndex); } if (SecureServer.MaxNumberOfClientSupported > SecureServer.NumberOfClientsConnected) { Listen(); } } } catch (Exception ex) { Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Change Callback. Error: {0}", ex); } //Use a thread for this event so that the server state updates to listening while this event is processed. Listening must be added to the server state //after every client connection so that the server can check and see if it is at max clients. Due to this the event fires and server listening enum bit flag //is not set. Putting in a thread allows the state to update before this event processes so that the subscribers to this event get accurate isListening in the event. CrestronInvoke.BeginInvoke(o => onConnectionChange(clientIndex, server.GetServerSocketStatusForSpecificClient(clientIndex)), null); }
/// <summary> /// Secure Received Data Async Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="numberOfBytesReceived"></param> void SecureReceivedDataAsyncCallback(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(SecureReceivedDataAsyncCallback); } 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(SecureReceivedDataAsyncCallback); } else { mySecureTCPServer.ReceiveDataAsync(SecureReceivedDataAsyncCallback); Debug.Console(2, "Secure Server Listening on Port: {0}, client IP: {1}, NumberOfBytesReceived: {2}, Received: {3}\r\n", mySecureTCPServer.PortNumber, mySecureTCPServer.GetAddressServerAcceptedConnectionFromForSpecificClient(clientIndex), numberOfBytesReceived, received); onTextReceived(received); } checkHeartbeat(clientIndex, received); } if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) { mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); } }
override protected void ReceiveCallback(SecureTCPServer myTCPServer, uint clientIndex, int numberOfBytesReceived) { try { if (numberOfBytesReceived > 0 && myTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex) != null) { byte[] data = new byte[numberOfBytesReceived]; Array.Copy(myTCPServer.GetIncomingDataBufferForSpecificClient(clientIndex), data, numberOfBytesReceived); myTCPServer.ReceiveDataAsync(clientIndex, ReceiveCallback); ParseFrame(clientIndex, data); } } catch (Exception e) { CrestronLogger.WriteToLog("MQTTSERVER - RECEIVE CALLBACK - " + " inner exception" + e.InnerException + " Error Message : " + e.Message, 8); CrestronLogger.WriteToLog("MQTTSERVER - RECEIVE CALLBACK - StackTrace : " + e.StackTrace, 8); CrestronLogger.WriteToLog("MQTTSERVER - RECEIVE CALLBACK - Exception occured , Disconnecting client", 8); DisconnectClient(clientIndex, false); } }
/// <summary> /// Secure TCP Client Connected to Secure Server Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> void SecureConnectCallback(SecureTCPServer mySecureTCPServer, uint clientIndex) { if (mySecureTCPServer.ClientConnected(clientIndex)) { if (SharedKeyRequired) { 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)); } if (HeartbeatRequired) { CTimer HeartbeatTimer = new CTimer(HeartbeatTimer_CallbackFunction, clientIndex, HeartbeatRequiredIntervalMs); HeartbeatTimerDictionary.Add(clientIndex, HeartbeatTimer); } mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); if (mySecureTCPServer.State != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped) { mySecureTCPServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); } } }
public void ServerConnectedCallback(SecureTCPServer server, uint clientIndex) { if (clientIndex != 0) { CrestronConsole.PrintLine("Server listening on port " + server.PortNumber + " has connected with a client (client #" + clientIndex + ")"); server.ReceiveDataAsync(clientIndex, ServerDataReceivedCallback); if (server.MaxNumberOfClientSupported == server.NumberOfClientsConnected) { CrestronConsole.PrintLine("Client limit reached."); // This call to Stop() causes the server.State flag, SERVER_NOT_LISTENING, to be set server.Stop(); CrestronConsole.PrintLine("After calling server.Stop(), the server state is: " + server.State); } // If the client limit is reached, WaitForConnectionAsync will return SOCKET_MAX_CONNECTIONS_REACHED // and the ServerConnectedCallback will not be registered. Otherwise, the call to WaitForConnectionAsync // causes the server to keep listening for more clients. SocketErrorCodes err = server.WaitForConnectionAsync(ServerConnectedCallback); PrintAndLog("WaitForConnectionAsync returned: " + err); } // A clientIndex of 0 could mean that the server is no longer listening, or that the TLS handshake failed when a client tried to connect. // In the case of a TLS handshake failure, wait for another connection so that other clients can still connect else { CrestronConsole.Print("Error in ServerConnectedCallback: "); if ((server.State & ServerState.SERVER_NOT_LISTENING) > 0) { CrestronConsole.PrintLine("Server is no longer listening."); } else { CrestronConsole.PrintLine("Unable to make connection with client."); // This connection failed, but keep waiting for another server.WaitForConnectionAsync(ServerConnectedCallback); } } }
protected void SendCallback(SecureTCPServer myTCPServer, uint clientIndex, int numberOfBytesSent) { // CrestronLogger.WriteToLog("MQTTServer - SEND CALLBACK - Data Sent to client " + GetClientByIndex(clientIndex).ClientId + " Number of bytes : " + numberOfBytesSent, 2); }
protected abstract void ReceiveCallback(SecureTCPServer myTCPServer, uint clientIndex, int numberOfBytesReceived);
protected abstract void ConnectionCallback(SecureTCPServer server, uint clientIndex);
/// <summary> /// Secure Received Data Async Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="numberOfBytesReceived"></param> void SecureReceivedDataAsyncCallback(SecureTCPServer mySecureTCPServer, uint clientIndex, int numberOfBytesReceived) { if (numberOfBytesReceived > 0) { string received = "Nothing"; var handler = TextReceivedQueueInvoke; try { 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(1, this, Debug.ErrorLogLevel.Warning, "Client at index {0} Shared key did not match the server, disconnecting client. Key: {1}", clientIndex, received); mySecureTCPServer.SendData(clientIndex, b, b.Length); mySecureTCPServer.Disconnect(clientIndex); return; } WaitingForSharedKey.Remove(clientIndex); byte[] success = Encoding.GetEncoding(28591).GetBytes("Shared Key Match"); mySecureTCPServer.SendDataAsync(clientIndex, success, success.Length, null); OnServerClientReadyForCommunications(clientIndex); Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Client with index {0} provided the shared key and successfully connected to the server", clientIndex); } else if (!string.IsNullOrEmpty(checkHeartbeat(clientIndex, received))) { onTextReceived(received, clientIndex); if (handler != null) { MessageQueue.TryToEnqueue(new GenericTcpServerCommMethodReceiveTextArgs(received, clientIndex)); } } } catch (Exception ex) { Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error Receiving data: {0}. Error: {1}", received, ex); } if (mySecureTCPServer.GetServerSocketStatusForSpecificClient(clientIndex) == SocketStatus.SOCKET_STATUS_CONNECTED) { mySecureTCPServer.ReceiveDataAsync(clientIndex, SecureReceivedDataAsyncCallback); } //Check to see if there is a subscription to the TextReceivedQueueInvoke event. If there is start the dequeue thread. if (handler != null) { var gotLock = DequeueLock.TryEnter(); if (gotLock) { CrestronInvoke.BeginInvoke((o) => DequeueEvent()); } } } else { mySecureTCPServer.Disconnect(clientIndex); } }
/// <summary> /// Secure Send Data Async Callback /// </summary> /// <param name="mySecureTCPServer"></param> /// <param name="clientIndex"></param> /// <param name="numberOfBytesSent"></param> void SecureSendDataAsyncCallback(SecureTCPServer mySecureTCPServer, uint clientIndex, int numberOfBytesSent) { //Seems there is nothing to do here }
/// <summary> /// The callback for receiving data from the secure server client. /// </summary> /// <param name="server">The server the callback is executed on.</param> /// <param name="clientIndex">The index of the client data is received from.</param> /// <param name="count">The number of bytes of data received.</param> private void SecureReceiveDataCallback(SecureTCPServer server, uint clientIndex, int count) { if (count <= 0) { if (server.ClientConnected(clientIndex)) { server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback); } return; } var dataBuffer = server.GetIncomingDataBufferForSpecificClient(clientIndex); var data = Encoding.UTF8.GetString(dataBuffer, 0, count); if (Regex.IsMatch(data, "^GET", RegexOptions.IgnoreCase)) { var key = Regex.Match(data, "Sec-WebSocket-Key: (.*)").Groups[1].Value.Trim(); key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; byte[] keySha1 = Crestron.SimplSharp.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key)); string sha64 = Convert.ToBase64String(keySha1); var responseMessage = "HTTP/1.1 101 Switching Protocols\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Accept: " + sha64 + "\r\n\r\n"; this.Send(responseMessage, clientIndex, false); } else { CrestronConsole.PrintLine("Received '{0}' bytes.", count); bool fin = (dataBuffer[0] & 128) != 0; bool mask = (dataBuffer[1] & 128) != 0; int opcode = dataBuffer[0] & 15; ulong dataLength = (ulong)(dataBuffer[1] - 128); ulong offset = 2; if (opcode == 0x0) { CrestronConsole.PrintLine("Received continuation frame opcode."); } else if (opcode == 0x1) { CrestronConsole.PrintLine("Received text frame opcode."); } else if (opcode == 0x2) { CrestronConsole.PrintLine("Received binary frame opcode."); } else if (opcode >= 0x3 && opcode <= 0x7) { CrestronConsole.PrintLine("Received reserved non-control opcode."); } else if (opcode == 0x8) { this.Send(new byte[] { BitConverter.GetBytes(0x88)[0], BitConverter.GetBytes(0x00)[0] }, clientIndex, false); server.Disconnect(clientIndex); CrestronConsole.PrintLine("Received disconnect OpCode. Disconnected."); return; } else if (opcode == 0x9) { this.Send(new byte[] { BitConverter.GetBytes(0x8A)[0], BitConverter.GetBytes(0x00)[0] }, clientIndex, false); CrestronConsole.PrintLine("Received Ping and sent a Pong."); if (server.ClientConnected(clientIndex)) { server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback); } return; } else if (opcode == 0xA) { CrestronConsole.PrintLine("Received Pong."); if (server.ClientConnected(clientIndex)) { server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback); } return; } else if (opcode >= 0xB && opcode <= 0xF) { CrestronConsole.PrintLine("Received reserved control frame opcode."); } if (dataLength == 126) { CrestronConsole.PrintLine("Data length is 126."); dataLength = BitConverter.ToUInt16(new byte[] { dataBuffer[3], dataBuffer[2] }, 0); offset = 4; } else if (dataLength == 127) { CrestronConsole.PrintLine("Data length is 127."); dataLength = BitConverter.ToUInt64(new byte[] { dataBuffer[9], dataBuffer[8], dataBuffer[7], dataBuffer[6], dataBuffer[5], dataBuffer[4], dataBuffer[3], dataBuffer[2] }, 0); offset = 10; } if (dataLength == 0) { CrestronConsole.PrintLine("Data length was zero."); this.Send(string.Format("{0}>", InitialParametersClass.ControllerPromptName), clientIndex, true); } else if (mask) { byte[] de = new byte[dataLength]; byte[] mk = new byte[4] { dataBuffer[offset], dataBuffer[offset + 1], dataBuffer[offset + 2], dataBuffer[offset + 3] }; offset += 4; for (ulong i = 0; i < dataLength; i++) { de[i] = (byte)(dataBuffer[offset + i] ^ mk[i % 4]); } var text = Encoding.UTF8.GetString(de, 0, de.Length); var dr = DataReceived; if (dr != null) { dr.Invoke(text, clientIndex); } } else { CrestronConsole.PrintLine("Data length was '{0}', but mask bit not set. Invalid message received.", dataLength); var dbg = string.Empty; for (var i = 0; i < count; i++) { dbg += string.Format("[{0}]", Convert.ToString(dataBuffer[i], 16)); } Debug.WriteDebugLine(this, dbg); } } if (server.ClientConnected(clientIndex)) { server.ReceiveDataAsync(clientIndex, SecureReceiveDataCallback); } }