/// <summary> /// Handles incoming commands from devices connected over the command channel. /// </summary> /// <param name="clientID">Guid of client that sent the command.</param> /// <param name="commandBuffer">Data buffer received from connected client device.</param> /// <param name="length">Valid length of data within the buffer.</param> protected override void DeviceCommandHandler(Guid clientID, byte[] commandBuffer, int length) { try { // Interpret data received from a client as a command frame CommandFrame commandFrame = new CommandFrame(commandBuffer, 0, length); TcpServer commandChannel = CommandChannel; switch (commandFrame.Command) { case DeviceCommand.SendConfigurationFrame1: case DeviceCommand.SendConfigurationFrame2: if (commandChannel != null) { commandChannel.SendToAsync(clientID, m_configurationFrame.BinaryImage); OnStatusMessage("Received device command \"{0}\" - frame was returned.", commandFrame.Command); } break; case DeviceCommand.SendHeaderFrame: if (commandChannel != null) { HeaderFrame headerFrame = new HeaderFrame("IEEE C37.118 Concentrator Status:\r\n\r\n" + Status); commandChannel.SendToAsync(clientID, headerFrame.BinaryImage); OnStatusMessage("Received device command \"SendHeaderFrame\" - frame was returned."); } break; case DeviceCommand.EnableRealTimeData: // Only responding to stream control command if auto-start data channel is false if (!AutoStartDataChannel) { StartDataChannel(); OnStatusMessage("Received device command \"EnableRealTimeData\" - concentrator real-time data stream was started."); } break; case DeviceCommand.DisableRealTimeData: // Only responding to stream control command if auto-start data channel is false if (!AutoStartDataChannel) { StopDataChannel(); OnStatusMessage("Received device command \"DisableRealTimeData\" - concentrator real-time data stream was stopped."); } break; default: OnStatusMessage("Received unsupported device command: {0}", commandFrame.Command); break; } } catch (Exception ex) { OnProcessException(new InvalidOperationException(string.Format("Encountered an exception while processing received client data: {0}", ex.Message), ex)); } }
/// <summary> /// Sends the specified <see cref="DeviceCommand"/> to the remote device. /// </summary> /// <param name="command"><see cref="DeviceCommand"/> to send to the remote device.</param> /// <remarks> /// Command will only be sent if <see cref="DeviceSupportsCommands"/> is <c>true</c> and <see cref="MultiProtocolFrameParser"/>. /// </remarks> public virtual void SendDeviceCommand(DeviceCommand command) { if (m_deviceSupportsCommands && (m_dataChannel != null || m_serverBasedDataChannel != null || m_commandChannel != null)) { ICommandFrame commandFrame; // Only the IEEE and SEL Fast Message protocols support commands switch (m_phasorProtocol) { case PhasorProtocols.PhasorProtocol.IeeeC37_118V1: case PhasorProtocols.PhasorProtocol.IeeeC37_118D6: commandFrame = new IeeeC37_118.CommandFrame(m_deviceID, command, 1); break; case PhasorProtocols.PhasorProtocol.Ieee1344: commandFrame = new Ieee1344.CommandFrame(m_deviceID, command); break; case PhasorProtocols.PhasorProtocol.SelFastMessage: // Get defined message period SelFastMessage.MessagePeriod messagePeriod = SelFastMessage.MessagePeriod.DefaultRate; SelFastMessage.ConnectionParameters connectionParameters = m_connectionParameters as SelFastMessage.ConnectionParameters; if (connectionParameters != null) messagePeriod = connectionParameters.MessagePeriod; commandFrame = new SelFastMessage.CommandFrame(command, messagePeriod); break; default: commandFrame = null; break; } if (commandFrame != null) { byte[] buffer = commandFrame.BinaryImage; // Send command over appropriate communications channel - command channel, if defined, // will take precedence over other communications channels for command traffic... if (m_commandChannel != null) m_commandChannel.SendAsync(buffer, 0, buffer.Length); else if (m_dataChannel != null) m_dataChannel.SendAsync(buffer, 0, buffer.Length); else m_serverBasedDataChannel.MulticastAsync(buffer, 0, buffer.Length); if (SentCommandFrame != null) SentCommandFrame(this, new EventArgs<ICommandFrame>(commandFrame)); } } }