Inheritance: CommandFrameBase
Exemple #1
0
        /// <summary>
        /// Casts the parsed <see cref="IChannelFrame"/> to its specific implementation (i.e., <see cref="DataFrame"/>, <see cref="ConfigurationFrame"/>, <see cref="CommandFrame"/> or <see cref="HeaderFrame"/>).
        /// </summary>
        /// <param name="frame"><see cref="IChannelFrame"/> that was parsed by <see cref="FrameImageParserBase{TTypeIdentifier,TOutputType}"/> that implements protocol specific common frame header interface.</param>
        protected override void OnReceivedChannelFrame(IChannelFrame frame)
        {
            // Raise abstract channel frame events as a priority (i.e., IDataFrame, IConfigurationFrame, etc.)
            base.OnReceivedChannelFrame(frame);

            // Raise IEEE C37.118 specific channel frame events, if any have been subscribed
            if (frame != null && (ReceivedDataFrame != null || ReceivedConfigurationFrame2 != null || ReceivedConfigurationFrame1 != null || ReceivedHeaderFrame != null || ReceivedCommandFrame != null))
            {
                DataFrame dataFrame = frame as DataFrame;

                if (dataFrame != null)
                {
                    if (ReceivedDataFrame != null)
                    {
                        ReceivedDataFrame(this, new EventArgs <DataFrame>(dataFrame));
                    }
                }
                else
                {
                    // Configuration frame type 2 is more specific than type 1 (and more common), so we check it first
                    ConfigurationFrame2 configFrame2 = frame as ConfigurationFrame2;

                    if (configFrame2 != null)
                    {
                        if (ReceivedConfigurationFrame2 != null)
                        {
                            ReceivedConfigurationFrame2(this, new EventArgs <ConfigurationFrame2>(configFrame2));
                        }
                    }
                    else
                    {
                        ConfigurationFrame1 configFrame1 = frame as ConfigurationFrame1;

                        if (configFrame1 != null)
                        {
                            if (ReceivedConfigurationFrame1 != null)
                            {
                                ReceivedConfigurationFrame1(this, new EventArgs <ConfigurationFrame1>(configFrame1));
                            }
                        }
                        else
                        {
                            HeaderFrame headerFrame = frame as HeaderFrame;

                            if (headerFrame != null)
                            {
                                if (ReceivedHeaderFrame != null)
                                {
                                    ReceivedHeaderFrame(this, new EventArgs <HeaderFrame>(headerFrame));
                                }
                            }
                            else
                            {
                                CommandFrame commandFrame = frame as CommandFrame;

                                if (commandFrame != null)
                                {
                                    if (ReceivedCommandFrame != null)
                                    {
                                        ReceivedCommandFrame(this, new EventArgs <CommandFrame>(commandFrame));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <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>
        /// <returns>A <see cref="WaitHandle"/>.</returns>
        public WaitHandle SendDeviceCommand(DeviceCommand command)
        {
            WaitHandle handle = null;

            try
            {
                if (m_deviceSupportsCommands && ((object)m_dataChannel != null || (object)m_serverBasedDataChannel != null || (object)m_commandChannel != null))
                {
                    ICommandFrame commandFrame;

                    // Only the IEEE, SEL Fast Message and Macrodyne protocols support commands
                    switch (m_phasorProtocol)
                    {
                        case PhasorProtocol.IEEEC37_118V2:
                        case PhasorProtocol.IEEEC37_118V1:
                        case PhasorProtocol.IEEEC37_118D6:
                            commandFrame = new IEEEC37_118.CommandFrame(m_deviceID, command, 1);
                            break;
                        case PhasorProtocol.IEEE1344:
                            commandFrame = new IEEE1344.CommandFrame(m_deviceID, command);
                            break;
                        case PhasorProtocol.IEC61850_90_5:
                            commandFrame = new IEC61850_90_5.CommandFrame(m_deviceID, command, 1);
                            break;
                        case PhasorProtocol.SelFastMessage:
                            // Get defined message period
                            MessagePeriod messagePeriod = MessagePeriod.DefaultRate;
                            SelFastMessage.ConnectionParameters connectionParameters = m_connectionParameters as SelFastMessage.ConnectionParameters;

                            if ((object)connectionParameters != null)
                                messagePeriod = connectionParameters.MessagePeriod;

                            commandFrame = new SelFastMessage.CommandFrame(command, messagePeriod);
                            break;
                        case PhasorProtocol.Macrodyne:
                            commandFrame = new Macrodyne.CommandFrame(command);
                            break;
                        default:
                            commandFrame = null;
                            break;
                    }

                    if ((object)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 ((object)m_commandChannel != null && m_commandChannel.CurrentState == ClientState.Connected)
                        {
                            handle = m_commandChannel.SendAsync(buffer, 0, buffer.Length);
                        }
                        else if ((object)m_dataChannel != null && m_dataChannel.CurrentState == ClientState.Connected)
                        {
                            handle = m_dataChannel.SendAsync(buffer, 0, buffer.Length);
                        }
                        else if ((object)m_serverBasedDataChannel != null && m_serverBasedDataChannel.CurrentState == ServerState.Running)
                        {
                            WaitHandle[] handles = m_serverBasedDataChannel.MulticastAsync(buffer, 0, buffer.Length);

                            if ((object)handles != null && handles.Length > 0)
                                handle = handles[0];
                        }

                        if ((object)SentCommandFrame != null)
                            SentCommandFrame(this, new EventArgs<ICommandFrame>(commandFrame));
                    }
                }
            }
            catch (Exception ex)
            {
                OnParsingException(ex, "Failed to send device command \"{0}\": {1}", command, ex.Message);
            }

            return handle;
        }
Exemple #3
0
        /// <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="connectionID">Remote client connection identification (i.e., IP:Port).</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, string connectionID, byte[] commandBuffer, int length)
        {
            try
            {
                // Interpret data received from a client as a command frame
                CommandFrame commandFrame = new CommandFrame(commandBuffer, 0, length);
                IServer commandChannel = (IServer)CommandChannel ?? DataChannel;

                // Validate incoming ID code if requested
                if (!m_validateIDCode || commandFrame.IDCode == this.IDCode)
                {
                    switch (commandFrame.Command)
                    {
                        case DeviceCommand.SendConfigurationFrame1:
                        case DeviceCommand.SendConfigurationFrame2:
                            if (commandChannel != null)
                            {
                                commandChannel.SendToAsync(clientID, m_configurationFrame.BinaryImage, 0, m_configurationFrame.BinaryLength);
                                OnStatusMessage("Received request for \"{0}\" from \"{1}\" - frame was returned.", commandFrame.Command, connectionID);
                            }
                            break;
                        case DeviceCommand.SendHeaderFrame:
                            if (commandChannel != null)
                            {
                                StringBuilder status = new StringBuilder();
                                status.Append("IEEE C37.118 Concentrator:\r\n\r\n");
                                status.AppendFormat(" Auto-publish config frame: {0}\r\n", AutoPublishConfigurationFrame);
                                status.AppendFormat("   Auto-start data channel: {0}\r\n", AutoStartDataChannel);
                                status.AppendFormat("       Data stream ID code: {0}\r\n", IDCode);
                                status.AppendFormat("       Derived system time: {0} UTC\r\n", ((DateTime)RealTime).ToString("yyyy-MM-dd HH:mm:ss.fff"));

                                HeaderFrame headerFrame = new HeaderFrame(status.ToString());
                                commandChannel.SendToAsync(clientID, headerFrame.BinaryImage, 0, headerFrame.BinaryLength);
                                OnStatusMessage("Received request for \"SendHeaderFrame\" from \"{0}\" - frame was returned.", connectionID);
                            }
                            break;
                        case DeviceCommand.EnableRealTimeData:
                            // Only responding to stream control command if auto-start data channel is false
                            if (!AutoStartDataChannel)
                            {
                                StartDataChannel();
                                OnStatusMessage("Received request for \"EnableRealTimeData\" from \"{0}\" - concentrator real-time data stream was started.", connectionID);
                            }
                            else
                                OnStatusMessage("Request for \"EnableRealTimeData\" from \"{0}\" was ignored - concentrator data channel is set for auto-start.", connectionID);

                            break;
                        case DeviceCommand.DisableRealTimeData:
                            // Only responding to stream control command if auto-start data channel is false
                            if (!AutoStartDataChannel)
                            {
                                StopDataChannel();
                                OnStatusMessage("Received request for \"DisableRealTimeData\" from \"{0}\" - concentrator real-time data stream was stopped.", connectionID);
                            }
                            else
                                OnStatusMessage("Request for \"DisableRealTimeData\" from \"{0}\" was ignored - concentrator data channel is set for auto-start.", connectionID);

                            break;
                        default:
                            OnStatusMessage("Request for \"{0}\" from \"{1}\" was ignored - device command is unsupported.", commandFrame.Command, connectionID);
                            break;
                    }
                }
                else
                    OnStatusMessage("WARNING: Concentrator ID code validation failed for device command \"{0}\" from \"{1}\" - no action was taken.", commandFrame.Command, connectionID);
            }
            catch (Exception ex)
            {
                OnProcessException(new InvalidOperationException(string.Format("Remotely connected device \"{0}\" sent an unrecognized data sequence to the concentrator, no action was taken. Exception details: {1}", connectionID, ex.Message), ex));
            }
        }