Esempio n. 1
0
        /// <summary>
        /// Verifies that the variable or variable type attributes are consistent with each other.
        /// </summary>
        private bool VerifyVariableBaseConsistency(IVariableBase node)
        {
            INode datatype = Session.NodeCache.Find(node.DataType) as INode;

            if (datatype == null || datatype.NodeClass != NodeClass.DataType)
            {
                Log(
                    "DataType is not recognized for Node '{0}'. NodeId = {1}, DataType = {2}",
                    node,
                    node.NodeId,
                    node.DataType);

                return(false);
            }

            if (node.ValueRank < -3)
            {
                Log(
                    "ValueRank is invalid for  Node '{0}'. NodeId = {1}, ValueRank = {2}",
                    node,
                    node.NodeId,
                    node.ValueRank);

                return(false);
            }

            if (node.ValueRank <= 0)
            {
                if (node.ArrayDimensions != null && node.ArrayDimensions.Count > 0)
                {
                    Log(
                        "ArrayDimensions not allowed for variable length values Node '{0}'. NodeId = {1}, ValueRank = {2}, ArrayDimensions = {3}",
                        node,
                        node.NodeId,
                        node.ValueRank,
                        new Variant(node.ArrayDimensions));

                    return(false);
                }
            }

            else
            {
                if (node.ArrayDimensions != null && node.ArrayDimensions.Count > 0 && node.ArrayDimensions.Count != node.ValueRank)
                {
                    Log(
                        "ArrayDimensions length does not match ValueRank values Node '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                        node,
                        node.NodeId,
                        node.ValueRank,
                        node.ArrayDimensions.Count);

                    return(false);
                }
            }

            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes the control.
        /// </summary>
        public void Initialize(Session session, NodeId typeId)
        {
            ItemsLV.Items.Clear();
            AdjustColumns();

            if (session == null)
            {
                return;
            }

            ILocalNode root = session.NodeCache.Find(typeId) as ILocalNode;

            if (root == null)
            {
                return;
            }

            m_session = session;

            SortedDictionary <string, InstanceDeclaration> instances =
                new SortedDictionary <string, InstanceDeclaration>();

            InstanceDeclaration declaration = new InstanceDeclaration();

            declaration.Instance    = root;
            declaration.DisplayPath = Utils.Format("({0})", root.NodeClass);
            declaration.Description = Utils.Format("{0}", root.Description);
            declaration.DataType    = "NodeId";

            IVariableBase variable = root as IVariableBase;

            if (variable != null)
            {
                INode dataType = m_session.NodeCache.Find(variable.DataType);

                if (dataType != null)
                {
                    declaration.DataType = Utils.Format("{0}", dataType);
                }

                if (variable.ValueRank >= 0)
                {
                    declaration.DataType += "[]";
                }
            }

            instances.Add(declaration.DisplayPath, declaration);

            CollectInstances(root, String.Empty, instances);

            foreach (InstanceDeclaration instance in instances.Values)
            {
                AddItem(instance);
            }

            AdjustColumns();
        }
Esempio n. 3
0
        /// <summary>
        /// Verifies the index range result for a scalar value.
        /// </summary>
        private bool VerifyIndexRangeForArray(IVariableBase variable, BuiltInType type, string indexRange,
                                              DataValue result)
        {
            // allow DA status codes.
            if (IsDaBadStatus(result.StatusCode))
            {
                return(true);
            }

            Array array = result.Value as Array;

            if (array == null)
            {
                if (result.StatusCode != StatusCodes.BadIndexRangeNoData)
                {
                    Log(
                        "Wrong error code when reading index range for array value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                        variable,
                        variable.NodeId,
                        variable.Value,
                        result.StatusCode);

                    return(false);
                }

                return(true);
            }

            if (indexRange == "10000000:20000000")
            {
                Log(
                    "Expected BadIndexRangeNoData for array value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                    variable,
                    variable.NodeId,
                    variable.Value,
                    result.Value);

                return(false);
            }

            if (array.Length > 2)
            {
                Log(
                    "Too much data return when reading index range for array value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                    variable,
                    variable.NodeId,
                    variable.Value,
                    result.Value);

                return(false);
            }


            return(true);
        }
Esempio n. 4
0
        /// <summary>
        /// Prompts the user to edit the read request parameters for the set of nodes provided.
        /// </summary>
        public ReadValueId[] ShowDialog(Session session, params ReadValueId[] nodesToRead)
        {
            NodeBTN.Session           = session;
            NodeBTN.SelectedReference = null;

            bool editNode         = true;
            bool editAttribute    = true;
            bool editIndexRange   = true;
            bool editDataEncoding = true;

            // populate the controls.
            if (nodesToRead != null && nodesToRead.Length > 0)
            {
                bool nonValueAttribute = false;

                for (int ii = 0; ii < nodesToRead.Length; ii++)
                {
                    if (nodesToRead[ii] == null)
                    {
                        continue;
                    }

                    // only show the node if all have the same node id.
                    if (editNode)
                    {
                        if (NodeBTN.SelectedNode != null && nodesToRead[ii].NodeId != NodeBTN.SelectedNode)
                        {
                            NodeTB.Visible  = false;
                            NodeLB.Visible  = false;
                            NodeBTN.Visible = false;
                            editNode        = false;
                        }
                        else
                        {
                            NodeBTN.SelectedNode = nodesToRead[ii].NodeId;
                        }
                    }

                    // only show the attribute if all have the same attribute id.
                    if (editAttribute)
                    {
                        // check if any non-value attributes are present.
                        if (nodesToRead[ii].AttributeId != Attributes.Value)
                        {
                            nonValueAttribute = true;
                        }

                        int index = (int)nodesToRead[ii].AttributeId - 1;

                        if (AttributeCB.SelectedIndex != -1 && index != AttributeCB.SelectedIndex)
                        {
                            AttributeCB.Visible = false;
                            AttributeLB.Visible = false;
                            editAttribute       = false;
                        }
                        else
                        {
                            AttributeCB.SelectedIndex = index;
                        }
                    }
                }

                DataEncodingCB.Items.Clear();
                editIndexRange = !nonValueAttribute;

                IndexRangeLB.Visible = editIndexRange;
                IndexRangeTB.Visible = editIndexRange;

                if (!nonValueAttribute)
                {
                    // use the index range for the first node as template.
                    IndexRangeTB.Text = nodesToRead[0].IndexRange;

                    // fetch the available encodings for the first node in the list from the server.
                    IVariableBase variable = session.NodeCache.Find(nodesToRead[0].NodeId) as IVariableBase;

                    if (variable != null)
                    {
                        if (session.NodeCache.IsTypeOf(variable.DataType, Opc.Ua.DataTypeIds.Structure))
                        {
                            DataEncodingCB.Items.Add(new EncodingInfo());
                            DataEncodingCB.SelectedIndex = 0;

                            foreach (INode encoding in session.NodeCache.Find(variable.DataType, Opc.Ua.ReferenceTypeIds.HasEncoding, false, true))
                            {
                                DataEncodingCB.Items.Add(new EncodingInfo()
                                {
                                    EncodingName = encoding.BrowseName
                                });

                                if (nodesToRead[0].DataEncoding == encoding.BrowseName)
                                {
                                    DataEncodingCB.SelectedIndex = DataEncodingCB.Items.Count - 1;
                                }
                            }
                        }
                    }
                }

                // hide the data encodings if none to select.
                if (DataEncodingCB.Items.Count == 0)
                {
                    DataEncodingCB.Visible = false;
                    DataEncodingLB.Visible = false;
                    editDataEncoding       = false;
                }
            }

            if (!editNode && !editAttribute && !editIndexRange && !editDataEncoding)
            {
                throw new ArgumentException("nodesToRead", "It is not possible to edit the current selection as a group.");
            }

            if (base.ShowDialog() != DialogResult.OK)
            {
                return(null);
            }

            // create the list of results.
            ReadValueId[] results = null;

            if (nodesToRead == null || nodesToRead.Length == 0)
            {
                results = new ReadValueId[1];
            }
            else
            {
                results = new ReadValueId[nodesToRead.Length];
            }

            // copy the controls into the results.
            for (int ii = 0; ii < results.Length; ii++)
            {
                // preserve the existing settings if they are not being changed.
                if (nodesToRead != null && nodesToRead.Length > 0)
                {
                    results[ii] = (ReadValueId)nodesToRead[ii].Clone();
                }
                else
                {
                    results[ii] = new ReadValueId();
                }

                // only copy results that were actually being edited.
                if (editNode)
                {
                    results[ii].NodeId = NodeBTN.SelectedNode;
                }

                if (editAttribute)
                {
                    results[ii].AttributeId = (uint)(AttributeCB.SelectedIndex + 1);
                }

                if (editIndexRange)
                {
                    results[ii].ParsedIndexRange = NumericRange.Parse(IndexRangeTB.Text);

                    if (NumericRange.Empty != results[ii].ParsedIndexRange)
                    {
                        results[ii].IndexRange = results[ii].ParsedIndexRange.ToString();
                    }
                    else
                    {
                        results[ii].IndexRange = String.Empty;
                    }
                }

                if (editDataEncoding)
                {
                    results[ii].DataEncoding = null;

                    EncodingInfo encoding = DataEncodingCB.SelectedItem as EncodingInfo;

                    if (encoding != null)
                    {
                        results[ii].DataEncoding = encoding.EncodingName;
                    }
                }
            }

            return(results);
        }
        /// <summary>
        /// Collects the instance declarations to display in the control.
        /// </summary>
        private void CollectInstances(ILocalNode parent, string basePath, SortedDictionary <string, InstanceDeclaration> instances)
        {
            if (parent == null)
            {
                return;
            }

            IList <IReference> supertypes = parent.References.Find(
                ReferenceTypeIds.HasSubtype,
                true,
                false,
                m_session.TypeTree);

            for (int ii = 0; ii < supertypes.Count; ii++)
            {
                ILocalNode supertype = m_session.NodeCache.Find(supertypes[ii].TargetId) as ILocalNode;

                if (supertype == null)
                {
                    continue;
                }

                CollectInstances(supertype, basePath, instances);
            }

            IList <IReference> children = parent.References.Find(
                ReferenceTypeIds.HierarchicalReferences,
                false,
                true,
                m_session.TypeTree);

            for (int ii = 0; ii < children.Count; ii++)
            {
                ILocalNode child = m_session.NodeCache.Find(children[ii].TargetId) as ILocalNode;

                if (child == null)
                {
                    continue;
                }

                if (child.NodeClass != NodeClass.Object && child.NodeClass != NodeClass.Variable)
                {
                    continue;
                }

                if (child.ModellingRule != Objects.ModellingRule_Mandatory && child.ModellingRule != Objects.ModellingRule_Optional)
                {
                    continue;
                }

                string displayPath = Utils.Format("{0}", child);

                if (!String.IsNullOrEmpty(basePath))
                {
                    displayPath = Utils.Format("{0}/{1}", basePath, displayPath);
                }

                InstanceDeclaration declaration = new InstanceDeclaration();

                declaration.Instance    = child;
                declaration.DisplayPath = displayPath;
                declaration.Description = Utils.Format("{0}", child.Description);
                declaration.DataType    = String.Empty;

                IVariableBase variable = child as IVariableBase;

                if (variable != null)
                {
                    INode dataType = m_session.NodeCache.Find(variable.DataType);

                    if (dataType != null)
                    {
                        declaration.DataType = Utils.Format("{0}", dataType);
                    }

                    if (variable.ValueRank >= 0)
                    {
                        declaration.DataType += "[]";
                    }
                }

                IObject objectn = child as IObject;

                if (objectn != null)
                {
                    declaration.DataType = "NodeId";
                }

                instances[displayPath] = declaration;
                CollectInstances(child, displayPath, instances);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Verifies that the variable or variable type attributes are consistent with each other.
        /// </summary>
        private bool VerifyVariableBaseConsistency(IVariableBase node)
        {
            INode datatype = Session.NodeCache.Find(node.DataType) as INode;

            if (datatype == null || datatype.NodeClass != NodeClass.DataType)
            {
                Log(
                    "DataType is not recognized for Node '{0}'. NodeId = {1}, DataType = {2}",
                    node,
                    node.NodeId,
                    node.DataType);

                return false;
            }

            if (node.ValueRank < -3)
            {
                Log(
                    "ValueRank is invalid for  Node '{0}'. NodeId = {1}, ValueRank = {2}",
                    node,
                    node.NodeId,
                    node.ValueRank);

                return false;
            }

            if (node.ValueRank <= 0)
            {
                if (node.ArrayDimensions != null && node.ArrayDimensions.Count > 0)
                {
                    Log(
                        "ArrayDimensions not allowed for variable length values Node '{0}'. NodeId = {1}, ValueRank = {2}, ArrayDimensions = {3}",
                        node,
                        node.NodeId,
                        node.ValueRank,
                        new Variant(node.ArrayDimensions));

                    return false;
                }
            }

            else
            {
                if (node.ArrayDimensions != null && node.ArrayDimensions.Count > 0 && node.ArrayDimensions.Count != node.ValueRank)
                {
                    Log(
                        "ArrayDimensions length does not match ValueRank values Node '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                        node,
                        node.NodeId,
                        node.ValueRank,
                        node.ArrayDimensions.Count);

                    return false;
                }
            }

            return true;
        }
Esempio n. 7
0
        /// <summary>
        /// Displays the value in the control.
        /// </summary>
        public void ShowValue(
            NodeId nodeId,
            uint attributeId,
            string name,
            object value,
            bool readOnly)
        {
            m_readOnly = readOnly;
            NavigationMENU.Items.Clear();

            if (m_readOnly)
            {
                ValuesDV.EditMode    = DataGridViewEditMode.EditProgrammatically;
                TextValueTB.ReadOnly = true;
            }

            Type type = null;

            // determine the expected data type for non-value attributes.
            if (attributeId != 0 && attributeId != Attributes.Value)
            {
                BuiltInType builtInType = TypeInfo.GetBuiltInType(Attributes.GetDataTypeId(attributeId));
                int         valueRank   = Attributes.GetValueRank(attributeId);
                type = TypeInfo.GetSystemType(builtInType, valueRank);
            }

            // determine the expected data type for value attributes.
            else if (!NodeId.IsNull(nodeId))
            {
                IVariableBase variable = m_session.NodeCache.Find(nodeId) as IVariableBase;

                if (variable != null)
                {
                    BuiltInType builtInType = TypeInfo.GetBuiltInType(variable.DataType, m_session.TypeTree);
                    int         valueRank   = variable.ValueRank;
                    type = TypeInfo.GetSystemType(builtInType, valueRank);

                    if (builtInType == BuiltInType.ExtensionObject && valueRank < 0)
                    {
                        type = TypeInfo.GetSystemType(variable.DataType, m_session.Factory);
                    }
                }
            }

            // use the value.
            else if (value != null)
            {
                type = value.GetType();
            }

            // go with default.
            else
            {
                type = typeof(string);
            }

            // assign a name.
            if (String.IsNullOrEmpty(name))
            {
                if (attributeId != 0)
                {
                    name = Attributes.GetBrowseName(attributeId);
                }
                else
                {
                    name = type.Name;
                }
            }

            AccessInfo info = new AccessInfo();

            info.Value    = Utils.Clone(value);
            info.TypeInfo = TypeInfo.Construct(type);

            if (value == null && info.TypeInfo.ValueRank < 0)
            {
                info.Value = TypeInfo.GetDefaultValue(info.TypeInfo.BuiltInType);
            }

            info.Name = name;
            m_value   = info;

            ShowValue(info);
        }
Esempio n. 8
0
        /// <summary>
        /// Verifies that the node attributes are consistent with each other.
        /// </summary>
        protected bool VerifyAttributeConsistency(Node node)
        {
            if (((~node.WriteMask) & node.UserWriteMask) != 0)
            {
                Log(
                    "UserWriteMask allows more access that WriteMask for  Node '{0}'. NodeId = {1}, WriteMask = {2}, UserWriteMask = {3}",
                    node,
                    node.NodeId,
                    node.WriteMask,
                    node.UserWriteMask);

                return(false);
            }

            IMethod method = node as IMethod;

            if (method != null)
            {
                if (method.UserExecutable && !method.Executable)
                {
                    Log(
                        "UserExecutable allows more access that Executable for  Node '{0}'. NodeId = {1}, Executable = {2}, UserExecutable = {3}",
                        node,
                        node.NodeId,
                        method.Executable,
                        method.UserExecutable);

                    return(false);
                }
            }

            IVariableBase variableBase = node as IVariableBase;

            if (variableBase != null)
            {
                if (!VerifyVariableBaseConsistency(variableBase))
                {
                    return(false);
                }
            }

            IVariable variable = node as IVariable;

            if (variable != null)
            {
                if (!VerifyVariableConsistency(variable))
                {
                    return(false);
                }
            }

            IVariableType variableType = node as IVariableType;

            if (variableType != null)
            {
                if (!VerifyVariableTypeConsistency(variableType))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Prompts the user to edit the monitored item.
        /// </summary>
        public bool ShowDialog(Session session, MonitoredItem monitoredItem, bool isEvent)
        {
            if (!monitoredItem.Created)
            {
                NodeBTN.Session      = session;
                NodeBTN.SelectedNode = monitoredItem.StartNodeId;
            }

            // hide fields not used for events.
            NodeLB.Visible             = !monitoredItem.Created;
            NodeTB.Visible             = !monitoredItem.Created;
            NodeBTN.Visible            = !monitoredItem.Created;
            AttributeLB.Visible        = !isEvent && !monitoredItem.Created;
            AttributeCB.Visible        = !isEvent && !monitoredItem.Created;
            IndexRangeLB.Visible       = !isEvent && !monitoredItem.Created;
            IndexRangeTB.Visible       = !isEvent && !monitoredItem.Created;
            DataEncodingLB.Visible     = !isEvent && !monitoredItem.Created;
            DataEncodingCB.Visible     = !isEvent && !monitoredItem.Created;
            MonitoringModeLB.Visible   = !monitoredItem.Created;
            MonitoringModeCB.Visible   = !monitoredItem.Created;
            SamplingIntervalLB.Visible = true;
            SamplingIntervalUP.Visible = true;
            QueueSizeLB.Visible        = !isEvent;
            QueueSizeUP.Visible        = !isEvent;
            DiscardOldestLB.Visible    = true;
            DiscardOldestCK.Visible    = true;
            DeadbandTypeLB.Visible     = !isEvent;
            DeadbandTypeCB.Visible     = !isEvent;
            DeadbandValueLB.Visible    = !isEvent;
            DeadbandValueUP.Visible    = !isEvent;
            TriggerTypeLB.Visible      = !isEvent;
            TriggerTypeCB.Visible      = !isEvent;

            // fill in values.
            SamplingIntervalUP.Value = monitoredItem.SamplingInterval;
            DiscardOldestCK.Checked  = monitoredItem.DiscardOldest;

            if (!isEvent)
            {
                AttributeCB.SelectedIndex     = (int)(monitoredItem.AttributeId - 1);
                IndexRangeTB.Text             = monitoredItem.IndexRange;
                MonitoringModeCB.SelectedItem = monitoredItem.MonitoringMode;
                QueueSizeUP.Value             = monitoredItem.QueueSize;

                DataChangeFilter filter = monitoredItem.Filter as DataChangeFilter;

                if (filter != null)
                {
                    DeadbandTypeCB.SelectedItem = (DeadbandType)filter.DeadbandType;
                    DeadbandValueUP.Value       = (decimal)filter.DeadbandValue;
                    TriggerTypeCB.SelectedItem  = filter.Trigger;
                }

                if (!monitoredItem.Created)
                {
                    // fetch the available encodings for the first node in the list from the server.
                    IVariableBase variable = session.NodeCache.Find(monitoredItem.StartNodeId) as IVariableBase;

                    DataEncodingCB.Items.Add(new EncodingInfo());
                    DataEncodingCB.SelectedIndex = 0;

                    if (variable != null)
                    {
                        if (session.NodeCache.IsTypeOf(variable.DataType, Opc.Ua.DataTypeIds.Structure))
                        {
                            foreach (INode encoding in session.NodeCache.Find(variable.DataType, Opc.Ua.ReferenceTypeIds.HasEncoding, false, true))
                            {
                                DataEncodingCB.Items.Add(new EncodingInfo()
                                {
                                    EncodingName = encoding.BrowseName
                                });

                                if (monitoredItem.Encoding == encoding.BrowseName)
                                {
                                    DataEncodingCB.SelectedIndex = DataEncodingCB.Items.Count - 1;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                AttributeCB.SelectedIndex = ((int)Attributes.EventNotifier - 1);
            }

            if (base.ShowDialog() != DialogResult.OK)
            {
                return(false);
            }

            // update monitored item.
            if (!monitoredItem.Created)
            {
                monitoredItem.StartNodeId    = NodeBTN.SelectedNode;
                monitoredItem.DisplayName    = session.NodeCache.GetDisplayText(monitoredItem.StartNodeId);
                monitoredItem.RelativePath   = null;
                monitoredItem.AttributeId    = (uint)(AttributeCB.SelectedIndex + 1);
                monitoredItem.MonitoringMode = (MonitoringMode)MonitoringModeCB.SelectedItem;
            }

            monitoredItem.SamplingInterval = (int)SamplingIntervalUP.Value;
            monitoredItem.DiscardOldest    = DiscardOldestCK.Checked;

            if (!isEvent)
            {
                if (!monitoredItem.Created)
                {
                    monitoredItem.IndexRange = IndexRangeTB.Text.Trim();
                    monitoredItem.Encoding   = ((EncodingInfo)DataEncodingCB.SelectedItem).EncodingName;
                }

                monitoredItem.QueueSize = (uint)QueueSizeUP.Value;

                DataChangeTrigger trigger      = (DataChangeTrigger)TriggerTypeCB.SelectedItem;
                DeadbandType      deadbandType = (DeadbandType)DeadbandTypeCB.SelectedItem;

                if (monitoredItem.Filter != null || deadbandType != DeadbandType.None || trigger != DataChangeTrigger.StatusValue)
                {
                    DataChangeFilter filter = new DataChangeFilter();
                    filter.DeadbandType  = (uint)deadbandType;
                    filter.DeadbandValue = (double)DeadbandValueUP.Value;
                    filter.Trigger       = trigger;
                    monitoredItem.Filter = filter;
                }
            }
            else
            {
                if (!monitoredItem.Created)
                {
                    monitoredItem.IndexRange = null;
                    monitoredItem.Encoding   = null;
                }

                monitoredItem.QueueSize = 0;
                monitoredItem.Filter    = new EventFilter();
            }

            return(true);
        }
Esempio n. 10
0
        /// <summary>
        /// Verifies the index range result for a scalar value.
        /// </summary>
        private bool VerifyIndexRangeForScalar(IVariableBase variable, BuiltInType type, DataValue result)
        {
            // allow DA status codes to be returned before checking the
            if (IsDaBadStatus(result.StatusCode))
            {
                return(true);
            }

            if (result.StatusCode != StatusCodes.BadIndexRangeInvalid)
            {
                if (type != BuiltInType.ByteString && type != BuiltInType.String && type != BuiltInType.Variant)
                {
                    Log(
                        "Wrong error code when reading index range for scalar value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                        variable,
                        variable.NodeId,
                        variable.Value,
                        result.StatusCode);

                    return(false);
                }

                if (type == BuiltInType.String)
                {
                    string value = result.Value as string;

                    if (value != null && value.Length > 2)
                    {
                        Log(
                            "Too much data return when reading index range for sting value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.Value);

                        return(false);
                    }
                }

                if (type == BuiltInType.ByteString)
                {
                    byte[] value = result.Value as byte[];

                    if (value != null && value.Length > 2)
                    {
                        Log(
                            "Too much data return when reading index range for ByteString value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.Value);

                        return(false);
                    }
                }

                if (type == BuiltInType.Variant)
                {
                    Array value = result.Value as Array;

                    if (value != null && value.Length > 2)
                    {
                        Log(
                            "Too much data return when reading index range for Variant value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.Value);

                        return(false);
                    }
                }
            }
            else
            {
                if (type == BuiltInType.ByteString || type == BuiltInType.String)
                {
                    Log(
                        "Error returned reading index range for ByteString or String value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                        variable,
                        variable.NodeId,
                        variable.Value,
                        result.StatusCode);

                    return(false);
                }
            }

            return(true);
        }
Esempio n. 11
0
        private bool VerifyDataEncoding(IVariableBase variable, BuiltInType type, QualifiedName dataEncoding,
                                        DataValue result)
        {
            // allow DA status codes to be returned before checking the
            if (IsDaBadStatus(result.StatusCode))
            {
                return(true);
            }

            IList <INode> encodings = Session.NodeCache.Find(
                variable.DataType,
                ReferenceTypeIds.HasEncoding,
                false,
                true);

            if (StatusCode.IsBad(result.StatusCode))
            {
                for (int ii = 0; ii < encodings.Count; ii++)
                {
                    if (encodings[ii].BrowseName == dataEncoding)
                    {
                        Log(
                            "Did not return a valid value for a supported data encoding '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.StatusCode);

                        return(false);
                    }
                }

                return(true);
            }

            ExtensionObject extension = result.Value as ExtensionObject;

            if (extension != null)
            {
                for (int ii = 0; ii < encodings.Count; ii++)
                {
                    if (encodings[ii].BrowseName == dataEncoding)
                    {
                        if (ExpandedNodeId.ToNodeId(extension.TypeId, Session.NamespaceUris) != encodings[ii].NodeId)
                        {
                            Log(
                                "Did not return value with correct data encoding '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                                variable,
                                variable.NodeId,
                                encodings[ii].NodeId,
                                extension.TypeId);

                            return(false);
                        }
                    }
                }
            }

            ExtensionObject[] extensions = result.Value as ExtensionObject[];

            if (extensions != null)
            {
                for (int jj = 0; jj < extensions.Length; jj++)
                {
                    extension = extensions[jj];

                    for (int ii = 0; ii < encodings.Count; ii++)
                    {
                        if (encodings[ii].BrowseName == dataEncoding)
                        {
                            if (ExpandedNodeId.ToNodeId(extension.TypeId, Session.NamespaceUris) !=
                                encodings[ii].NodeId)
                            {
                                Log(
                                    "Did not return value with correct data encoding '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                                    variable,
                                    variable.NodeId,
                                    encodings[ii].NodeId,
                                    extension.TypeId);

                                return(false);
                            }
                        }
                    }
                }
            }

            return(true);
        }
Esempio n. 12
0
        /// <summary>
        /// Reads the attributes, verifies the results and updates the nodes.
        /// </summary>
        private bool Read(ReadValueIdCollection nodesToRead)
        {
            bool success = true;

            DataValueCollection      results;
            DiagnosticInfoCollection diagnosticInfos;

            RequestHeader requestHeader = new RequestHeader();

            requestHeader.ReturnDiagnostics = 0;

            Session.Read(
                requestHeader,
                0,
                TimestampsToReturn.Both,
                nodesToRead,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            // check diagnostics.
            if (diagnosticInfos != null && diagnosticInfos.Count > 0)
            {
                Log("Returned non-empty DiagnosticInfos array during Read.");
                return(false);
            }

            // check results.
            for (int ii = 0; ii < nodesToRead.Count; ii++)
            {
                ReadValueId request = nodesToRead[ii];
                Node        node    = (Node)request.Handle;

                if (!VerifyTimestamps(node, request.AttributeId, TimestampsToReturn.Both, results[ii]))
                {
                    success = false;
                    continue;
                }

                if (request.IndexRange == null && request.DataEncoding == null)
                {
                    if (StatusCode.IsBad(results[ii].StatusCode))
                    {
                        if (!VerifyBadAttribute(node, request.AttributeId, results[ii].StatusCode))
                        {
                            success = false;
                        }

                        continue;
                    }

                    if (!VerifyGoodAttribute(node, request.AttributeId, results[ii]))
                    {
                        success = false;
                        continue;
                    }
                }
                else if (request.IndexRange != null)
                {
                    if (request.AttributeId != Attributes.Value ||
                        (node.NodeClass != NodeClass.Variable && node.NodeClass != NodeClass.VariableType))
                    {
                        if (results[ii].StatusCode != StatusCodes.BadAttributeIdInvalid &&
                            results[ii].StatusCode != StatusCodes.BadIndexRangeInvalid)
                        {
                            Log(
                                "IndexRange not valid for non-value attributes '{0}'. NodeId = {1}, Attribute = {2}, StatusCode = {3}",
                                node,
                                node.NodeId,
                                Attributes.GetBrowseName(request.AttributeId),
                                results[ii].StatusCode);

                            success = false;
                            break;
                        }

                        continue;
                    }

                    // check for variable types with no value.
                    if (node.NodeClass == NodeClass.VariableType)
                    {
                        if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid)
                        {
                            continue;
                        }
                    }

                    // index range can be ignored if the value is null.
                    if (StatusCode.IsGood(results[ii].StatusCode) && results[ii].Value == null)
                    {
                        continue;
                    }

                    // check for access errors.
                    if (results[ii].StatusCode == StatusCodes.BadNotReadable ||
                        results[ii].StatusCode == StatusCodes.BadUserAccessDenied)
                    {
                        continue;
                    }

                    // check the result against the expected data type.
                    IVariableBase variable = node as IVariableBase;
                    BuiltInType   type     = TypeInfo.GetBuiltInType(variable.DataType, Session.TypeTree);

                    if (variable.ValueRank == ValueRanks.Scalar)
                    {
                        if (!VerifyIndexRangeForScalar(variable, type, results[ii]))
                        {
                            success = false;
                            break;
                        }
                    }
                    else
                    {
                        if (!VerifyIndexRangeForArray(variable, type, request.IndexRange, results[ii]))
                        {
                            success = false;
                            break;
                        }
                    }
                }

                if (request.DataEncoding != null)
                {
                    if (request.AttributeId != Attributes.Value ||
                        (node.NodeClass != NodeClass.Variable && node.NodeClass != NodeClass.VariableType))
                    {
                        if (results[ii].StatusCode != StatusCodes.BadAttributeIdInvalid &&
                            results[ii].StatusCode != StatusCodes.BadDataEncodingInvalid &&
                            results[ii].StatusCode != StatusCodes.BadDataEncodingUnsupported)
                        {
                            Log(
                                "DataEncoding not valid for non-value attributes '{0}'. NodeId = {1}, Attribute = {2}, StatusCode = {3}",
                                node,
                                node.NodeId,
                                Attributes.GetBrowseName(request.AttributeId),
                                results[ii].StatusCode);

                            success = false;
                            break;
                        }

                        continue;
                    }

                    // check for variable types with no value.
                    if (node.NodeClass == NodeClass.VariableType)
                    {
                        if (results[ii].StatusCode == StatusCodes.BadAttributeIdInvalid)
                        {
                            continue;
                        }
                    }

                    // data encoding can be ignored if the value is null.
                    if (StatusCode.IsGood(results[ii].StatusCode) && results[ii].Value == null)
                    {
                        continue;
                    }

                    // check for access errors.
                    if (results[ii].StatusCode == StatusCodes.BadNotReadable ||
                        results[ii].StatusCode == StatusCodes.BadUserAccessDenied)
                    {
                        continue;
                    }

                    // check the result against the expected data type.
                    IVariableBase variable = node as IVariableBase;
                    BuiltInType   type     = TypeInfo.GetBuiltInType(variable.DataType, Session.TypeTree);

                    if (type != BuiltInType.ExtensionObject)
                    {
                        if (!IsDaBadStatus(results[ii].StatusCode))
                        {
                            if (results[ii].StatusCode != StatusCodes.BadDataEncodingInvalid &&
                                results[ii].StatusCode != StatusCodes.BadDataEncodingUnsupported)
                            {
                                Log(
                                    "Wrong error code when reading value with data encoding '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                                    variable,
                                    variable.NodeId,
                                    variable.Value,
                                    results[ii].StatusCode);

                                success = false;
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (!VerifyDataEncoding(variable, type, request.DataEncoding, results[ii]))
                        {
                            success = false;
                            break;
                        }
                    }
                }
            }

            // check attribute consistency.
            if (success)
            {
                Node current = null;

                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    if (Object.ReferenceEquals(current, nodesToRead[ii].Handle))
                    {
                        continue;
                    }

                    current = (Node)nodesToRead[ii].Handle;

                    if (!VerifyAttributeConsistency(current))
                    {
                        success = false;
                        continue;
                    }
                }
            }

            return(success);
        }
Esempio n. 13
0
        /// <summary>
        /// Verifies the index range result for a scalar value.
        /// </summary>
        private bool VerifyIndexRangeForScalar(IVariableBase variable, BuiltInType type, DataValue result)
        {
            // allow DA status codes to be returned before checking the 
            if (IsDaBadStatus(result.StatusCode))
            {
                return true;
            }

            if (result.StatusCode != StatusCodes.BadIndexRangeInvalid)
            {
                if (type != BuiltInType.ByteString && type != BuiltInType.String && type != BuiltInType.Variant)
                {
                    Log(
                        "Wrong error code when reading index range for scalar value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                        variable,
                        variable.NodeId,
                        variable.Value,
                        result.StatusCode);

                    return false;
                }

                if (type == BuiltInType.String)
                {
                    string value = result.Value as string;

                    if (value != null && value.Length > 2)
                    {
                        Log(
                            "Too much data return when reading index range for sting value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.Value);

                        return false;
                    }
                }

                if (type == BuiltInType.ByteString)
                {
                    byte[] value = result.Value as byte[];

                    if (value != null && value.Length > 2)
                    {
                        Log(
                            "Too much data return when reading index range for ByteString value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.Value);

                        return false;
                    }
                }

                if (type == BuiltInType.Variant)
                {
                    Array value = result.Value as Array;

                    if (value != null && value.Length > 2)
                    {
                        Log(
                            "Too much data return when reading index range for Variant value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.Value);

                        return false;
                    }
                }
            }
            else
            {
                if (type == BuiltInType.ByteString || type == BuiltInType.String)
                {
                    Log(
                        "Error returned reading index range for ByteString or String value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                        variable,
                        variable.NodeId,
                        variable.Value,
                        result.StatusCode);

                    return false;
                }
            }

            return true;
        }
Esempio n. 14
0
        private bool VerifyDataEncoding(IVariableBase variable, BuiltInType type, QualifiedName dataEncoding, DataValue result)
        {  
            // allow DA status codes to be returned before checking the 
            if (IsDaBadStatus(result.StatusCode))
            {
                return true;
            }

            IList<INode> encodings = Session.NodeCache.Find(
                variable.DataType,
                ReferenceTypeIds.HasEncoding,
                false,
                true);

            if (StatusCode.IsBad(result.StatusCode))
            {
                for (int ii = 0; ii < encodings.Count; ii++)
                {
                    if (encodings[ii].BrowseName == dataEncoding)
                    {
                        Log(
                            "Did not return a valid value for a supported data encoding '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                            variable,
                            variable.NodeId,
                            variable.Value,
                            result.StatusCode);

                        return false;
                    }
                }

                return true;
            }
                        
            ExtensionObject extension = result.Value as ExtensionObject;

            if (extension != null)
            {
                for (int ii = 0; ii < encodings.Count; ii++)
                {
                    if (encodings[ii].BrowseName == dataEncoding)
                    {
                        if (ExpandedNodeId.ToNodeId(extension.TypeId, Session.NamespaceUris) != encodings[ii].NodeId)
                        {
                            Log(
                                "Did not return value with correct data encoding '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                                variable,
                                variable.NodeId,
                                encodings[ii].NodeId,
                                extension.TypeId);

                            return false;
                        }
                    }
                }
            }
                        
            ExtensionObject[] extensions = result.Value as ExtensionObject[];

            if (extensions != null)
            {
                for (int jj = 0; jj < extensions.Length; jj++)
                {
                    extension = extensions[jj];

                    for (int ii = 0; ii < encodings.Count; ii++)
                    {
                        if (encodings[ii].BrowseName == dataEncoding)
                        {
                            if (ExpandedNodeId.ToNodeId(extension.TypeId, Session.NamespaceUris) != encodings[ii].NodeId)
                            {
                                Log(
                                    "Did not return value with correct data encoding '{0}'. NodeId = {1}, Expected = {2}, Actual = {3}",
                                    variable,
                                    variable.NodeId,
                                    encodings[ii].NodeId,
                                    extension.TypeId);

                                return false;
                            }
                        }
                    }
                }
            }

            return true;
        }
Esempio n. 15
0
        /// <summary>
        /// Verifies the index range result for a scalar value.
        /// </summary>
        private bool VerifyIndexRangeForArray(IVariableBase variable, BuiltInType type, string indexRange, DataValue result)
        {
            // allow DA status codes.
            if (IsDaBadStatus(result.StatusCode))
            {
                return true;
            }

            Array array = result.Value as Array;

            if (array == null)
            {
                if (result.StatusCode != StatusCodes.BadIndexRangeNoData)
                {
                    Log(
                        "Wrong error code when reading index range for array value '{0}'. NodeId = {1}, Value = {2}, StatusCode = {3}",
                        variable,
                        variable.NodeId,
                        variable.Value,
                        result.StatusCode);

                    return false;
                }

                return true;
            }

            if (indexRange == "10000000:20000000")
            {
                Log(
                    "Expected BadIndexRangeNoData for array value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                    variable,
                    variable.NodeId,
                    variable.Value,
                    result.Value);

                return false;
            }
            
            if (array.Length > 2)
            {
                Log(
                    "Too much data return when reading index range for array value '{0}'. NodeId = {1}, Value = {2}, ReturnedValue = {3}",
                    variable,
                    variable.NodeId,
                    variable.Value,
                    result.Value);

                return false;
            }


            return true;
        }