예제 #1
0
        /// <summary>
        /// Atempt to decode dataset from the Keyvalue pairs
        /// </summary>
        private void DecodePossibleDataSetReader(JsonDecoder jsonDecoder, DataSetReaderDataType dataSetReader)
        {
            // check if there shall be a dataset header and decode it
            if (HasDataSetMessageHeader)
            {
                DecodeDataSetMessageHeader(jsonDecoder);
            }

            if (dataSetReader.DataSetWriterId != 0 && DataSetWriterId != dataSetReader.DataSetWriterId)
            {
                return;
            }

            object token = null;
            string payloadStructureName = kFieldPayload;

            // try to read "Payload" structure
            if (!jsonDecoder.ReadField(kFieldPayload, out token))
            {
                // Decode the Messages element in case there is no "Payload" structure
                jsonDecoder.ReadField(null, out token);
                payloadStructureName = null;
            }

            Dictionary <string, object> payload = token as Dictionary <string, object>;

            if (payload != null)
            {
                if (payload.Count > dataSetReader.DataSetMetaData.Fields.Count)
                {
                    // filter out payload that has more fields than the searched datasetMetadata
                    return;
                }
                // check also the field names from reader, if any extra field names then the payload is not matching
                foreach (string key in payload.Keys)
                {
                    var field = dataSetReader.DataSetMetaData.Fields.FirstOrDefault(f => f.Name == key);
                    if (field == null)
                    {
                        // the field from payload was not found in dataSetReader therefore the payload is not suitable to be decoded
                        return;
                    }
                }
            }
            try
            {
                // try decoding Payload Structure
                bool wasPush = jsonDecoder.PushStructure(payloadStructureName);
                if (wasPush)
                {
                    DataSet = DecodePayloadContent(jsonDecoder, dataSetReader);
                }
            }
            finally
            {
                // redo decode stack
                jsonDecoder.Pop();
            }
        }
예제 #2
0
        /// <summary>
        /// Decode dataset from the provided json decoder using the provided <see cref="DataSetReaderDataType"/>.
        /// </summary>
        /// <param name="jsonDecoder">The json decoder that contains the json stream.</param>
        /// <param name="messagesCount">Number of Messages found in current jsonDecoder. If 0 then there is SingleDataSetMessage</param>
        /// <param name="messagesListName">The name of the Messages list</param>
        /// <param name="dataSetReader">The <see cref="DataSetReaderDataType"/> used to decode the data set.</param>
        public void DecodePossibleDataSetReader(JsonDecoder jsonDecoder, int messagesCount, string messagesListName, DataSetReaderDataType dataSetReader)
        {
            if (messagesCount == 0)
            {
                // check if there shall be a dataset header and decode it
                if (HasDataSetMessageHeader)
                {
                    DecodeDataSetMessageHeader(jsonDecoder);

                    // push into PayloadStructure if there was a dataset header
                    jsonDecoder.PushStructure(kFieldPayload);
                }

                DecodeErrorReason = ValidateMetadataVersion(dataSetReader?.DataSetMetaData?.ConfigurationVersion);
                if (IsMetadataMajorVersionChange)
                {
                    return;
                }
                // handle single dataset with no network message header & no dataset message header (the content of the payload)
                DataSet = DecodePayloadContent(jsonDecoder, dataSetReader);
            }
            else
            {
                for (int index = 0; index < messagesCount; index++)
                {
                    bool wasPush = jsonDecoder.PushArray(messagesListName, index);
                    if (wasPush)
                    {
                        // atempt decoding the DataSet fields
                        DecodePossibleDataSetReader(jsonDecoder, dataSetReader);

                        // redo jsonDecoder stack
                        jsonDecoder.Pop();

                        if (DataSet != null)
                        {
                            // the dataset was decoded
                            return;
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Decode the Content of the Payload and create a DataSet object from it
        /// </summary>
        private DataSet DecodePayloadContent(JsonDecoder jsonDecoder, DataSetReaderDataType dataSetReader)
        {
            TargetVariablesDataType targetVariablesData =
                ExtensionObject.ToEncodeable(dataSetReader.SubscribedDataSet) as TargetVariablesDataType;
            DataSetMetaDataType dataSetMetaData = dataSetReader.DataSetMetaData;

            object           token;
            List <DataValue> dataValues = new List <DataValue>();

            for (int index = 0; index < dataSetMetaData?.Fields.Count; index++)
            {
                FieldMetaData fieldMetaData = dataSetMetaData?.Fields[index];

                if (jsonDecoder.ReadField(fieldMetaData.Name, out token))
                {
                    switch (m_fieldTypeEncoding)
                    {
                    case FieldTypeEncodingMask.Variant:
                        Variant variantValue = jsonDecoder.ReadVariant(fieldMetaData.Name);
                        dataValues.Add(new DataValue(variantValue));
                        break;

                    case FieldTypeEncodingMask.RawData:
                        object value = DecodeRawData(jsonDecoder, dataSetMetaData?.Fields[index], dataSetMetaData?.Fields[index].Name);
                        dataValues.Add(new DataValue(new Variant(value)));
                        break;

                    case FieldTypeEncodingMask.DataValue:
                        bool      wasPush2  = jsonDecoder.PushStructure(fieldMetaData.Name);
                        DataValue dataValue = new DataValue(Variant.Null);
                        try
                        {
                            if (wasPush2 && jsonDecoder.ReadField("Value", out token))
                            {
                                // the Value was encoded using the non reversible json encoding
                                token     = DecodeRawData(jsonDecoder, dataSetMetaData?.Fields[index], "Value");
                                dataValue = new DataValue(new Variant(token));
                            }
                            else
                            {
                                // handle Good StatusCode that was not encoded
                                if (dataSetMetaData?.Fields[index].BuiltInType == (byte)BuiltInType.StatusCode)
                                {
                                    dataValue = new DataValue(new Variant(new StatusCode(StatusCodes.Good)));
                                }
                            }

                            if ((FieldContentMask & DataSetFieldContentMask.StatusCode) != 0)
                            {
                                if (jsonDecoder.ReadField("StatusCode", out token))
                                {
                                    bool wasPush3 = jsonDecoder.PushStructure("StatusCode");
                                    if (wasPush3)
                                    {
                                        dataValue.StatusCode = jsonDecoder.ReadStatusCode("Code");
                                        jsonDecoder.Pop();
                                    }
                                }
                            }

                            if ((FieldContentMask & DataSetFieldContentMask.SourceTimestamp) != 0)
                            {
                                dataValue.SourceTimestamp = jsonDecoder.ReadDateTime("SourceTimestamp");
                            }

                            if ((FieldContentMask & DataSetFieldContentMask.SourcePicoSeconds) != 0)
                            {
                                dataValue.SourcePicoseconds = jsonDecoder.ReadUInt16("SourcePicoseconds");
                            }

                            if ((FieldContentMask & DataSetFieldContentMask.ServerTimestamp) != 0)
                            {
                                dataValue.ServerTimestamp = jsonDecoder.ReadDateTime("ServerTimestamp");
                            }

                            if ((FieldContentMask & DataSetFieldContentMask.ServerPicoSeconds) != 0)
                            {
                                dataValue.ServerPicoseconds = jsonDecoder.ReadUInt16("ServerPicoseconds");
                            }
                            dataValues.Add(dataValue);
                        }
                        finally
                        {
                            if (wasPush2)
                            {
                                jsonDecoder.Pop();
                            }
                        }
                        break;
                    }
                }
                else
                {
                    switch (m_fieldTypeEncoding)
                    {
                    case FieldTypeEncodingMask.Variant:
                    case FieldTypeEncodingMask.RawData:
                        // handle StatusCodes.Good which is not encoded and therefore must be created at decode
                        if (dataSetMetaData?.Fields[index].BuiltInType == (byte)BuiltInType.StatusCode)
                        {
                            dataValues.Add(new DataValue(new Variant(new StatusCode(StatusCodes.Good))));
                        }
                        else
                        {
                            // the field is null
                            dataValues.Add(new DataValue(Variant.Null));
                        }
                        break;
                    }
                }
            }

            if (dataValues.Count != dataSetMetaData?.Fields.Count)
            {
                return(null);
            }

            //build the DataSet Fields collection based on the decoded values and the target
            List <Field> dataFields = new List <Field>();

            for (int i = 0; i < dataValues.Count; i++)
            {
                Field dataField = new Field();
                dataField.FieldMetaData = dataSetMetaData?.Fields[i];
                dataField.Value         = dataValues[i];

                if (targetVariablesData != null && targetVariablesData.TargetVariables != null &&
                    i < targetVariablesData.TargetVariables.Count)
                {
                    // remember the target Attribute and target nodeId
                    dataField.TargetAttribute = targetVariablesData.TargetVariables[i].AttributeId;
                    dataField.TargetNodeId    = targetVariablesData.TargetVariables[i].TargetNodeId;
                }
                dataFields.Add(dataField);
            }

            // build the dataset object
            DataSet dataSet = new DataSet(dataSetMetaData?.Name);

            dataSet.Fields          = dataFields.ToArray();
            dataSet.DataSetWriterId = DataSetWriterId;
            dataSet.SequenceNumber  = SequenceNumber;
            return(dataSet);
        }
예제 #4
0
        /// <summary>
        /// Decode the stream from decoder parameter and produce a Dataset
        /// </summary>
        /// <param name="jsonDecoder"></param>
        /// <param name="dataSetReaders"></param>
        /// <returns></returns>
        public void DecodeSubscribedDataSets(JsonDecoder jsonDecoder, IEnumerable <DataSetReaderDataType> dataSetReaders)
        {
            try
            {
                List <DataSetReaderDataType> dataSetReadersFiltered = new List <DataSetReaderDataType>();

                // 1. decode network message header (PublisherId & DataSetClassId)
                DecodeNetworkMessageHeader(jsonDecoder);

                // ignore network messages that are not dataSet messages
                if (m_jsonNetworkMessageType != JSONNetworkMessageType.DataSetMessage)
                {
                    return;
                }

                //* 6.2.8.1 PublisherId
                // The parameter PublisherId defines the Publisher to receive NetworkMessages from.
                // If the value is null, the parameter shall be ignored and all received NetworkMessages pass the PublisherId filter. */
                foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                {
                    if (dataSetReader.PublisherId == Variant.Null)
                    {
                        dataSetReadersFiltered.Add(dataSetReader);
                    }
                    // publisher id
                    else if ((NetworkMessageContentMask & JsonNetworkMessageContentMask.PublisherId) != 0 &&
                             PublisherId != null &&
                             PublisherId.Equals(dataSetReader.PublisherId.Value.ToString()))
                    {
                        dataSetReadersFiltered.Add(dataSetReader);
                    }
                }
                if (dataSetReadersFiltered.Count == 0)
                {
                    return;
                }
                dataSetReaders = dataSetReadersFiltered;

                object        messagesToken    = null;
                List <object> messagesList     = null;
                string        messagesListName = string.Empty;
                if (jsonDecoder.ReadField(kFieldMessages, out messagesToken))
                {
                    messagesList = messagesToken as List <object>;
                    if (messagesList == null)
                    {
                        // this is a SingleDataSetMessage encoded as the conteten of Messages
                        jsonDecoder.PushStructure(kFieldMessages);
                        messagesList = new List <object>();
                    }
                    else
                    {
                        messagesListName = kFieldMessages;
                    }
                }
                else if (jsonDecoder.ReadField(JsonDecoder.RootArrayName, out messagesToken))
                {
                    messagesList     = messagesToken as List <object>;
                    messagesListName = JsonDecoder.RootArrayName;
                }
                else
                {
                    // this is a SingleDataSetMessage encoded as the conteten of json
                    messagesList = new List <object>();
                }
                if (messagesList != null)
                {
                    // atempt decoding for each data set reader
                    foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                    {
                        JsonDataSetReaderMessageDataType jsonMessageSettings = ExtensionObject.ToEncodeable(dataSetReader.MessageSettings)
                                                                               as JsonDataSetReaderMessageDataType;
                        if (jsonMessageSettings == null)
                        {
                            // The reader MessageSettings is not set up corectly
                            continue;
                        }
                        JsonNetworkMessageContentMask networkMessageContentMask =
                            (JsonNetworkMessageContentMask)jsonMessageSettings.NetworkMessageContentMask;
                        if ((networkMessageContentMask & NetworkMessageContentMask) != NetworkMessageContentMask)
                        {
                            // The reader MessageSettings.NetworkMessageContentMask is not set up corectly
                            continue;
                        }

                        // initialize the dataset message
                        JsonDataSetMessage jsonDataSetMessage = new JsonDataSetMessage();
                        jsonDataSetMessage.DataSetMessageContentMask = (JsonDataSetMessageContentMask)jsonMessageSettings.DataSetMessageContentMask;
                        jsonDataSetMessage.SetFieldContentMask((DataSetFieldContentMask)dataSetReader.DataSetFieldContentMask);
                        // set the flag that indicates if dataset message shall have a header
                        jsonDataSetMessage.HasDataSetMessageHeader = (networkMessageContentMask & JsonNetworkMessageContentMask.DataSetMessageHeader) != 0;

                        jsonDataSetMessage.DecodePossibleDataSetReader(jsonDecoder, messagesList.Count, messagesListName, dataSetReader);
                        if (jsonDataSetMessage.DataSet != null)
                        {
                            m_uaDataSetMessages.Add(jsonDataSetMessage);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Unexpected exception in DecodeSubscribedDataSets
                Utils.Trace(ex, "JsonNetworkMessage.DecodeSubscribedDataSets");
            }
        }