public void ValidateUadpPubSubConnectionCreateNetworkMessageSequenceNumber()
        {
            Assert.IsNotNull(m_uadpPublisherConnection, "The UADP connection from standard configuration is invalid.");
            //Arrange
            WriterGroupDataType writerGroup0 = m_uadpPublisherConnection.PubSubConnectionConfiguration.WriterGroups[0];

            //Act
            m_uadpPublisherConnection.ResetSequenceNumber();
            for (int i = 0; i < 10; i++)
            {
                //Create network message
                UadpNetworkMessage networkMessage = m_uadpPublisherConnection.CreateNetworkMessage(writerGroup0) as UadpNetworkMessage;

                //Assert
                Assert.IsNotNull(networkMessage, "CreateNetworkMessage did not return an UadpNetworkMessage.");
                Assert.AreEqual(networkMessage.SequenceNumber, i + 1, "UadpNetworkMessage.SequenceNumber for message {0} is not {0}.", i + 1);

                //validate dataset message sequence number
                Assert.IsNotNull(networkMessage.UadpDataSetMessages, "CreateNetworkMessage did not return an UadpNetworkMessage.UadpDataSetMessages.");
                Assert.IsTrue(networkMessage.UadpDataSetMessages.Count == 3, "CreateNetworkMessage did not return 3 UadpNetworkMessage.UadpDataSetMessages.");
                Assert.AreEqual(networkMessage.UadpDataSetMessages[0].SequenceNumber, i * 3 + 1, "UadpNetworkMessage.UadpDataSetMessages[0].SequenceNumber for message {0} is not {1}.", i + 1, i * 3 + 1);
                Assert.AreEqual(networkMessage.UadpDataSetMessages[1].SequenceNumber, i * 3 + 2, "UadpNetworkMessage.UadpDataSetMessages[1].SequenceNumber for message {0} is not {1}.", i + 1, i * 3 + 2);
                Assert.AreEqual(networkMessage.UadpDataSetMessages[2].SequenceNumber, i * 3 + 3, "UadpNetworkMessage.UadpDataSetMessages[2].SequenceNumber for message {0} is not {1}.", i + 1, i * 3 + 3);
            }
        }
Пример #2
0
        /// <summary>
        /// Create and return the list of DataSetMetaData response messages
        /// </summary>
        /// <param name="dataSetWriterIds"></param>
        /// <returns></returns>
        public IList <UaNetworkMessage> CreateDataSetMetaDataNetworkMessages(UInt16[] dataSetWriterIds)
        {
            List <UaNetworkMessage> networkMessages = new List <UaNetworkMessage>();
            var writers = GetAllDataSetWriters();

            foreach (UInt16 dataSetWriterId in dataSetWriterIds)
            {
                DataSetWriterDataType writer = writers.Where(w => w.DataSetWriterId == dataSetWriterId).FirstOrDefault();
                if (writer != null)
                {
                    WriterGroupDataType writerGroup = PubSubConnectionConfiguration.WriterGroups.Where(wg => wg.DataSetWriters.Contains(writer)).FirstOrDefault();
                    if (writerGroup != null)
                    {
                        DataSetMetaDataType metaData = Application.DataCollector.GetPublishedDataSet(writer.DataSetName)?.DataSetMetaData;
                        if (metaData != null)
                        {
                            UadpNetworkMessage networkMessage = new UadpNetworkMessage(writerGroup, metaData);
                            networkMessage.PublisherId     = PubSubConnectionConfiguration.PublisherId.Value;
                            networkMessage.DataSetWriterId = dataSetWriterId;

                            networkMessages.Add(networkMessage);
                        }
                    }
                }
            }

            return(networkMessages);
        }
        public void ValidateUadpPubSubConnectionCreateNetworkMessage()
        {
            Assert.IsNotNull(m_uadpPublisherConnection, "The UADP connection from standard configuration is invalid.");

            //Arrange
            WriterGroupDataType            writerGroup0    = m_uadpPublisherConnection.PubSubConnectionConfiguration.WriterGroups[0];
            UadpWriterGroupMessageDataType messageSettings = ExtensionObject.ToEncodeable(writerGroup0.MessageSettings)
                                                             as UadpWriterGroupMessageDataType;

            //Act
            m_uadpPublisherConnection.ResetSequenceNumber();
            UadpNetworkMessage networkMessage0 = m_uadpPublisherConnection.CreateNetworkMessage(writerGroup0) as UadpNetworkMessage;

            //Assert
            Assert.IsNotNull(networkMessage0, "CreateNetworkMessage did not return an UadpNetworkMessage.");

            Assert.AreEqual(networkMessage0.DataSetClassId, Guid.Empty, "UadpNetworkMessage.DataSetClassId is invalid.");
            Assert.AreEqual(networkMessage0.WriterGroupId, writerGroup0.WriterGroupId, "UadpNetworkMessage.WriterGroupId is invalid.");
            Assert.AreEqual(networkMessage0.UADPVersion, 1, "UadpNetworkMessage.UADPVersion is invalid.");
            Assert.AreEqual(networkMessage0.SequenceNumber, 1, "UadpNetworkMessage.SequenceNumber is not 1.");
            Assert.AreEqual(networkMessage0.GroupVersion, messageSettings.GroupVersion, "UadpNetworkMessage.GroupVersion is not valid.");
            Assert.AreEqual(networkMessage0.PublisherId, m_uadpPublisherConnection.PubSubConnectionConfiguration.PublisherId.Value,
                            "UadpNetworkMessage.PublisherId is not valid.");
            Assert.IsNotNull(networkMessage0.UadpDataSetMessages, "UadpNetworkMessage.UadpDataSetMessages is null.");
            Assert.AreEqual(networkMessage0.UadpDataSetMessages.Count, 3, "UadpNetworkMessage.UadpDataSetMessages.Count is not 3.");
            //validate flags
            Assert.AreEqual((uint)networkMessage0.NetworkMessageContentMask, messageSettings.NetworkMessageContentMask,
                            "UadpNetworkMessage.messageSettings.NetworkMessageContentMask is not valid.");
        }
Пример #4
0
        /// <summary>
        /// Process the bytes received from UADP channel as Subscriber
        /// </summary>
        /// <param name="message"></param>
        /// <param name="source"></param>
        private void ProcessReceivedMessage(byte[] message, IPEndPoint source)
        {
            Utils.Trace(Utils.TraceMasks.Information, "UdpPubSubConnection.ProcessReceivedMessage from source={0}", source);

            List <DataSetReaderDataType> dataSetReaders         = GetOperationalDataSetReaders();
            List <DataSetReaderDataType> dataSetReadersToDecode = new List <DataSetReaderDataType>();

            foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
            {
                // check if dataSetReaders have metadata information
                if (!ConfigurationVersionUtils.IsUsable(dataSetReader.DataSetMetaData))
                {
                    // check if it is possible to request the metadata information
                    if (dataSetReader.DataSetWriterId != 0)
                    {
                        m_udpDiscoverySubscriber.AddWriterIdForDataSetMetadata(dataSetReader.DataSetWriterId);
                    }
                }
                else
                {
                    dataSetReadersToDecode.Add(dataSetReader);
                }
            }

            UadpNetworkMessage networkMessage = new UadpNetworkMessage();

            networkMessage.DataSetDecodeErrorOccurred += NetworkMessage_DataSetDecodeErrorOccurred;
            networkMessage.Decode(MessageContext, message, dataSetReadersToDecode);
            networkMessage.DataSetDecodeErrorOccurred -= NetworkMessage_DataSetDecodeErrorOccurred;

            // Process the decoded network message
            ProcessDecodedNetworkMessage(networkMessage, source.ToString());
        }
        public void ValidateUdpPubSubConnectionCreateNetworkMessageSequenceNumber()
        {
            Assert.IsNotNull(m_udpPublisherConnection, "The UADP connection from standard configuration is invalid.");
            //Arrange
            WriterGroupDataType writerGroup0 = m_udpPublisherConnection.PubSubConnectionConfiguration.WriterGroups.First();

            //Act
            m_udpPublisherConnection.ResetSequenceNumber();
            for (int i = 0; i < 10; i++)
            {
                // Create network message
                var networkMessages = m_udpPublisherConnection.CreateNetworkMessages(writerGroup0, new WriterGroupPublishState());
                Assert.IsNotNull(networkMessages, "connection.CreateNetworkMessages shall not return null");
                var networkMessagesNetworkType = networkMessages.FirstOrDefault(net => net.IsMetaDataMessage == false);
                Assert.IsNotNull(networkMessagesNetworkType, "connection.CreateNetworkMessages shall return only one network message");

                UadpNetworkMessage networkMessage = networkMessagesNetworkType as UadpNetworkMessage;
                Assert.IsNotNull(networkMessage, "networkMessageEncode should not be null");

                //Assert
                Assert.IsNotNull(networkMessage, "CreateNetworkMessage did not return an UadpNetworkMessage.");
                Assert.AreEqual(networkMessage.SequenceNumber, i + 1, "UadpNetworkMessage.SequenceNumber for message {0} is not {0}.", i + 1);

                //validate dataset message sequence number
                Assert.IsNotNull(networkMessage.DataSetMessages, "CreateNetworkMessage did not return an UadpNetworkMessage.UadpDataSetMessages.");
                Assert.IsTrue(networkMessage.DataSetMessages.Count == 3, "CreateNetworkMessage did not return 3 UadpNetworkMessage.UadpDataSetMessages.");
                Assert.AreEqual(((UadpDataSetMessage)networkMessage.DataSetMessages[0]).SequenceNumber, i * 3 + 1, "UadpNetworkMessage.UadpDataSetMessages[0].SequenceNumber for message {0} is not {1}.", i + 1, i * 3 + 1);
                Assert.AreEqual(((UadpDataSetMessage)networkMessage.DataSetMessages[1]).SequenceNumber, i * 3 + 2, "UadpNetworkMessage.UadpDataSetMessages[1].SequenceNumber for message {0} is not {1}.", i + 1, i * 3 + 2);
                Assert.AreEqual(((UadpDataSetMessage)networkMessage.DataSetMessages[2]).SequenceNumber, i * 3 + 3, "UadpNetworkMessage.UadpDataSetMessages[2].SequenceNumber for message {0} is not {1}.", i + 1, i * 3 + 3);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="fieldContentMask"> a DataSetFieldContentMask specifying what type of encoding is chosen for field values
        /// If none of the flags are set, the fields are represented as Variant.
        /// If the RawData flag is set, the fields are represented as RawData and all other bits are ignored.
        /// If one of the bits StatusCode, SourceTimestamp, ServerTimestamp, SourcePicoSeconds, ServerPicoSeconds is set,
        ///    the fields are represented as DataValue.
        /// </param>
        /// <returns></returns>
        private UadpDataSetMessage GetFirstDataSetMessage(DataSetFieldContentMask fieldContentMask)
        {
            LoadData();

            // set the configurable field content mask to allow only Variant data type
            foreach (DataSetWriterDataType dataSetWriter in m_firstWriterGroup.DataSetWriters)
            {
                // 00 The DataSet fields are encoded as Variant data type
                // The Variant can contain a StatusCode instead of the expected DataType if the status of the field is Bad.
                // The Variant can contain a DataValue with the value and the statusCode if the status of the field is Uncertain.
                dataSetWriter.DataSetFieldContentMask = (uint)fieldContentMask;
            }

            var networkMessages = m_firstPublisherConnection.CreateNetworkMessages(m_firstWriterGroup, new WriterGroupPublishState());

            Assert.IsNotNull(networkMessages, "connection.CreateNetworkMessages shall not return null");
            Assert.AreEqual(1, networkMessages.Count, "connection.CreateNetworkMessages shall return only one network message");

            UadpNetworkMessage uaNetworkMessage = networkMessages[0] as UadpNetworkMessage;

            Assert.IsNotNull(uaNetworkMessage, "networkMessageEncode should not be null");

            // read first dataset message
            UaDataSetMessage[] uadpDataSetMessages = uaNetworkMessage.DataSetMessages.ToArray();
            Assert.IsNotEmpty(uadpDataSetMessages, "uadpDataSetMessages collection should not be empty");

            UaDataSetMessage uadpDataSetMessage = uadpDataSetMessages[0];

            Assert.IsNotNull(uadpDataSetMessage, "uadpDataSetMessage should not be null");

            return(uadpDataSetMessage as UadpDataSetMessage);
        }
Пример #7
0
        /// <summary>
        /// Process the bytes received from UADP discovery channel
        /// </summary>
        private void ProcessReceivedMessageDiscovery(byte[] messageBytes, IPEndPoint source)
        {
            Utils.Trace(Utils.TraceMasks.Information, "UdpDiscoveryPublisher.ProcessReceivedMessageDiscovery from source={0}", source);

            UadpNetworkMessage networkMessage = new UadpNetworkMessage();

            // decode the received message
            networkMessage.Decode(MessageContext, messageBytes, null);

            if (networkMessage.UADPNetworkMessageType == UADPNetworkMessageType.DiscoveryRequest &&
                networkMessage.UADPDiscoveryType == UADPNetworkMessageDiscoveryType.DataSetMetaData &&
                networkMessage.DataSetWriterIds != null)
            {
                Utils.Trace(Utils.TraceMasks.Information, "UdpDiscoveryPublisher.ProcessReceivedMessageDiscovery Request MetaData Received on endpoint {1} for {0}",
                            String.Join(", ", networkMessage.DataSetWriterIds), source.Address);

                foreach (UInt16 dataSetWriterId in networkMessage.DataSetWriterIds)
                {
                    lock (m_lock)
                    {
                        if (!m_metadataWriterIdsToSend.Contains(dataSetWriterId))
                        {
                            // collect requested ids
                            m_metadataWriterIdsToSend.Add(dataSetWriterId);
                        }
                    }
                }

                Task.Run(SendResponseDataSetMetaData).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Process the bytes received from UADP channel
        /// </summary>
        /// <param name="message"></param>
        /// <param name="source"></param>
        private void ProcessReceivedMessage(byte[] message, IPEndPoint source)
        {
            Utils.Trace(Utils.TraceMasks.Information, "UdpPubSubConnection.ProcessReceivedMessage from source={0}", source);

            UadpNetworkMessage networkMessage = new UadpNetworkMessage();

            networkMessage.Decode(message, GetOperationalDataSetReaders());

            // Raise rhe DataReceived event
            RaiseNetworkMessageDataReceivedEvent(networkMessage, source.ToString());
        }
Пример #9
0
        /// <summary>
        /// Create and Send the DiscoveryRequest messages for DataSetMetaData
        /// </summary>
        private void SendDiscoveryRequestDataSetMetaData()
        {
            UInt16[] dataSetWriterIds = null;
            lock (m_lock)
            {
                dataSetWriterIds = m_metadataWriterIdsToSend.ToArray();
                m_metadataWriterIdsToSend.Clear();
            }

            if (dataSetWriterIds == null || dataSetWriterIds.Length == 0)
            {
                return;
            }

            // create the DataSetMetaData DiscoveryRequest message
            UadpNetworkMessage discoveryRequestMetaDataMessage = new UadpNetworkMessage(UADPNetworkMessageDiscoveryType.DataSetMetaData)
            {
                DataSetWriterIds = dataSetWriterIds,
                PublisherId      = m_udpConnection.PubSubConnectionConfiguration.PublisherId.Value,
            };

            byte[] bytes = discoveryRequestMetaDataMessage.Encode(MessageContext);

            // send the DataSetMetaData DiscoveryRequest message to all open UDPClient
            foreach (var udpClient in m_discoveryUdpClients)
            {
                try
                {
                    Utils.Trace("UdpDiscoverySubscriber.SendDiscoveryRequestDataSetMetaData Before sending message for DataSetWriterIds:{0}",
                                String.Join(", ", dataSetWriterIds));

                    udpClient.Send(bytes, bytes.Length, DiscoveryNetworkAddressEndPoint);
                }
                catch (Exception ex)
                {
                    Utils.Trace(ex, "UdpDiscoverySubscriber.SendDiscoveryRequestDataSetMetaData");
                }
            }

            // double the time between requests
            m_intervalRunner.Interval = m_intervalRunner.Interval * 2;
        }
        public void ValidateUdpPubSubConnectionCreateNetworkMessage()
        {
            Assert.IsNotNull(m_udpPublisherConnection, "The UADP connection from standard configuration is invalid.");

            //Arrange
            WriterGroupDataType            writerGroup0    = m_udpPublisherConnection.PubSubConnectionConfiguration.WriterGroups.First();
            UadpWriterGroupMessageDataType messageSettings = ExtensionObject.ToEncodeable(writerGroup0.MessageSettings)
                                                             as UadpWriterGroupMessageDataType;

            //Act
            m_udpPublisherConnection.ResetSequenceNumber();

            var networkMessages = m_udpPublisherConnection.CreateNetworkMessages(writerGroup0, new WriterGroupPublishState());

            Assert.IsNotNull(networkMessages, "connection.CreateNetworkMessages shall not return null");
            var networkMessagesNetworkType = networkMessages.FirstOrDefault(net => net.IsMetaDataMessage == false);

            Assert.IsNotNull(networkMessagesNetworkType, "connection.CreateNetworkMessages shall return only one network message");

            UadpNetworkMessage networkMessage0 = networkMessagesNetworkType as UadpNetworkMessage;

            Assert.IsNotNull(networkMessage0, "networkMessageEncode should not be null");

            //Assert
            Assert.IsNotNull(networkMessage0, "CreateNetworkMessage did not return an UadpNetworkMessage.");

            Assert.AreEqual(networkMessage0.DataSetClassId, Guid.Empty, "UadpNetworkMessage.DataSetClassId is invalid.");
            Assert.AreEqual(networkMessage0.WriterGroupId, writerGroup0.WriterGroupId, "UadpNetworkMessage.WriterGroupId is invalid.");
            Assert.AreEqual(networkMessage0.UADPVersion, 1, "UadpNetworkMessage.UADPVersion is invalid.");
            Assert.AreEqual(networkMessage0.SequenceNumber, 1, "UadpNetworkMessage.SequenceNumber is not 1.");
            Assert.AreEqual(networkMessage0.GroupVersion, messageSettings.GroupVersion, "UadpNetworkMessage.GroupVersion is not valid.");
            Assert.AreEqual(networkMessage0.PublisherId, m_udpPublisherConnection.PubSubConnectionConfiguration.PublisherId.Value,
                            "UadpNetworkMessage.PublisherId is not valid.");
            Assert.IsNotNull(networkMessage0.DataSetMessages, "UadpNetworkMessage.UadpDataSetMessages is null.");
            Assert.AreEqual(networkMessage0.DataSetMessages.Count, 3, "UadpNetworkMessage.UadpDataSetMessages.Count is not 3.");
            //validate flags
            Assert.AreEqual((uint)networkMessage0.NetworkMessageContentMask, messageSettings.NetworkMessageContentMask,
                            "UadpNetworkMessage.messageSettings.NetworkMessageContentMask is not valid.");
        }
        public void ValidateMqttLocalPubSubConnectionWithUadp(
            [Values((byte)1, (UInt16)1, (UInt32)1, (UInt64)1, "abc")] object publisherId)
        {
            RestartMosquitto("mosquitto");

            //Arrange
            UInt16 writerGroupId = 1;

            string mqttLocalBrokerUrl = "mqtt://localhost:1883";

            ITransportProtocolConfiguration mqttConfiguration = new MqttClientProtocolConfiguration(version: EnumMqttProtocolVersion.V500);

            UadpNetworkMessageContentMask uadpNetworkMessageContentMask = UadpNetworkMessageContentMask.PublisherId
                                                                          | UadpNetworkMessageContentMask.WriterGroupId
                                                                          | UadpNetworkMessageContentMask.PayloadHeader;
            UadpDataSetMessageContentMask uadpDataSetMessageContentMask = UadpDataSetMessageContentMask.None;

            DataSetFieldContentMask dataSetFieldContentMask = DataSetFieldContentMask.None;

            DataSetMetaDataType[] dataSetMetaDataArray = new DataSetMetaDataType[]
            {
                MessagesHelper.CreateDataSetMetaData1("DataSet1"),
                MessagesHelper.CreateDataSetMetaData2("DataSet2"),
                MessagesHelper.CreateDataSetMetaData3("DataSet3")
            };

            PubSubConfigurationDataType publisherConfiguration = MessagesHelper.CreatePublisherConfiguration(
                Profiles.PubSubMqttUadpTransport,
                mqttLocalBrokerUrl, publisherId: publisherId, writerGroupId: writerGroupId,
                uadpNetworkMessageContentMask: uadpNetworkMessageContentMask,
                uadpDataSetMessageContentMask: uadpDataSetMessageContentMask,
                dataSetFieldContentMask: dataSetFieldContentMask,
                dataSetMetaDataArray: dataSetMetaDataArray, nameSpaceIndexForData: kNamespaceIndexAllTypes);

            Assert.IsNotNull(publisherConfiguration, "publisherConfiguration should not be null");

            // Configure the mqtt publisher configuration with the MQTTbroker
            PubSubConnectionDataType mqttPublisherConnection = MessagesHelper.GetConnection(publisherConfiguration, publisherId);

            Assert.IsNotNull(mqttPublisherConnection, "The MQTT publisher connection is invalid.");
            mqttPublisherConnection.ConnectionProperties = mqttConfiguration.ConnectionProperties;
            Assert.IsNotNull(mqttPublisherConnection.ConnectionProperties, "The MQTT publisher connection properties are not valid.");

            // Create publisher application for multiple datasets
            UaPubSubApplication publisherApplication = UaPubSubApplication.Create(publisherConfiguration);

            MessagesHelper.LoadData(publisherApplication, kNamespaceIndexAllTypes);

            IUaPubSubConnection publisherConnection = publisherApplication.PubSubConnections.First();

            Assert.IsNotNull(publisherConnection, "Publisher first connection should not be null");

            Assert.IsNotNull(publisherConfiguration.Connections.First(), "publisherConfiguration first connection should not be null");
            Assert.IsNotNull(publisherConfiguration.Connections.First().WriterGroups.First(), "publisherConfiguration  first writer group of first connection should not be null");

            var networkMessages = publisherConnection.CreateNetworkMessages(publisherConfiguration.Connections.First().WriterGroups.First(), new WriterGroupPublishState());

            Assert.IsNotNull(networkMessages, "connection.CreateNetworkMessages shall not return null");
            Assert.GreaterOrEqual(networkMessages.Count, 1, "connection.CreateNetworkMessages shall have at least one network message");

            UadpNetworkMessage uaNetworkMessage = networkMessages[0] as UadpNetworkMessage;

            Assert.IsNotNull(uaNetworkMessage, "networkMessageEncode should not be null");

            bool hasDataSetWriterId = (uadpNetworkMessageContentMask & UadpNetworkMessageContentMask.PayloadHeader) != 0;

            PubSubConfigurationDataType subscriberConfiguration = MessagesHelper.CreateSubscriberConfiguration(
                Profiles.PubSubMqttUadpTransport,
                mqttLocalBrokerUrl, publisherId: publisherId, writerGroupId: writerGroupId, setDataSetWriterId: hasDataSetWriterId,
                uadpNetworkMessageContentMask: uadpNetworkMessageContentMask,
                uadpDataSetMessageContentMask: uadpDataSetMessageContentMask,
                dataSetFieldContentMask: dataSetFieldContentMask,
                dataSetMetaDataArray: dataSetMetaDataArray, nameSpaceIndexForData: kNamespaceIndexAllTypes);

            Assert.IsNotNull(subscriberConfiguration, "subscriberConfiguration should not be null");

            // Create subscriber application for multiple datasets
            UaPubSubApplication subscriberApplication = UaPubSubApplication.Create(subscriberConfiguration);

            Assert.IsNotNull(subscriberApplication, "subscriberApplication should not be null");
            Assert.IsNotNull(subscriberApplication.PubSubConnections.First(), "subscriberConfiguration first connection should not be null");

            // Configure the mqtt subscriber configuration with the MQTTbroker
            PubSubConnectionDataType mqttSubcriberConnection = MessagesHelper.GetConnection(subscriberConfiguration, publisherId);

            Assert.IsNotNull(mqttSubcriberConnection, "The MQTT subscriber connection is invalid.");
            mqttSubcriberConnection.ConnectionProperties = mqttConfiguration.ConnectionProperties;
            Assert.IsNotNull(mqttSubcriberConnection.ConnectionProperties, "The MQTT subscriber connection properties are not valid.");

            var dataSetReaders = subscriberApplication.PubSubConnections.First().GetOperationalDataSetReaders();

            Assert.IsNotNull(dataSetReaders, "dataSetReaders should not be null");
            IUaPubSubConnection subscriberConnection = subscriberApplication.PubSubConnections.First();

            Assert.IsNotNull(subscriberConnection, "Subscriber first connection should not be null");

            //Act
            // it will signal if the uadp message was received from local ip
            m_uaDataShutdownEvent = new ManualResetEvent(false);

            subscriberApplication.DataReceived += UaPubSubApplication_DataReceived;
            subscriberConnection.Start();

            publisherConnection.Start();

            //Assert
            if (!m_uaDataShutdownEvent.WaitOne(kEstimatedPublishingTime))
            {
                Assert.Fail("The UADP message was not received");
            }

            subscriberConnection.Stop();
            publisherConnection.Stop();
        }
        /// <summary>
        /// Create the list of network messages built from the provided writerGroupConfiguration
        /// </summary>
        public override IList <UaNetworkMessage> CreateNetworkMessages(WriterGroupDataType writerGroupConfiguration)
        {
            UadpWriterGroupMessageDataType messageSettings = ExtensionObject.ToEncodeable(writerGroupConfiguration.MessageSettings)
                                                             as UadpWriterGroupMessageDataType;

            if (messageSettings == null)
            {
                //Wrong configuration of writer group MessageSettings
                return(null);
            }
            DatagramWriterGroupTransportDataType transportSettings = ExtensionObject.ToEncodeable(writerGroupConfiguration.TransportSettings)
                                                                     as DatagramWriterGroupTransportDataType;

            if (transportSettings == null)
            {
                //Wrong configuration of writer group TransportSettings
                return(null);
            }

            //Create list of dataSet messages to be sent
            List <UaDataSetMessage> dataSetMessages = new List <UaDataSetMessage>();

            foreach (DataSetWriterDataType dataSetWriter in writerGroupConfiguration.DataSetWriters)
            {
                //check if dataSetWriter enabled
                if (dataSetWriter.Enabled)
                {
                    DataSet dataSet = Application.DataCollector.CollectData(dataSetWriter.DataSetName);
                    if (dataSet != null)
                    {
                        UadpDataSetWriterMessageDataType dataSetMessageSettings =
                            ExtensionObject.ToEncodeable(dataSetWriter.MessageSettings) as
                            UadpDataSetWriterMessageDataType;
                        // check MessageSettings to see how to encode DataSet
                        if (dataSetMessageSettings != null)
                        {
                            UadpDataSetMessage uadpDataSetMessage = new UadpDataSetMessage(dataSet);
                            uadpDataSetMessage.DataSetWriterId = dataSetWriter.DataSetWriterId;
                            uadpDataSetMessage.SetMessageContentMask((UadpDataSetMessageContentMask)dataSetMessageSettings.DataSetMessageContentMask);
                            uadpDataSetMessage.SetFieldContentMask((DataSetFieldContentMask)dataSetWriter.DataSetFieldContentMask);
                            uadpDataSetMessage.SequenceNumber = (ushort)(Utils.IncrementIdentifier(ref m_dataSetSequenceNumber) % UInt16.MaxValue);
                            uadpDataSetMessage.ConfiguredSize = dataSetMessageSettings.ConfiguredSize;
                            uadpDataSetMessage.DataSetOffset  = dataSetMessageSettings.DataSetOffset;
                            uadpDataSetMessage.Timestamp      = DateTime.UtcNow;
                            uadpDataSetMessage.Status         = StatusCodes.Good;
                            dataSetMessages.Add(uadpDataSetMessage);
                        }
                    }
                }
            }

            //cancel send if no dataset message
            if (dataSetMessages.Count == 0)
            {
                return(null);
            }

            UadpNetworkMessage uadpNetworkMessage = new UadpNetworkMessage(writerGroupConfiguration, dataSetMessages);

            uadpNetworkMessage.SetNetworkMessageContentMask((UadpNetworkMessageContentMask)messageSettings.NetworkMessageContentMask);
            uadpNetworkMessage.WriterGroupId = writerGroupConfiguration.WriterGroupId;
            // Network message header
            uadpNetworkMessage.PublisherId    = PubSubConnectionConfiguration.PublisherId.Value;
            uadpNetworkMessage.SequenceNumber = (ushort)(Utils.IncrementIdentifier(ref m_sequenceNumber) % UInt16.MaxValue);

            // Writer group header
            uadpNetworkMessage.GroupVersion         = messageSettings.GroupVersion;
            uadpNetworkMessage.NetworkMessageNumber = 1; //only one network message per publish

            return(new List <UaNetworkMessage>()
            {
                uadpNetworkMessage
            });
        }