/// <summary> /// Validates a filter for a monitored item. /// </summary> private ServiceResult ValidateFilter( NodeMetadata metadata, uint attributeId, ExtensionObject filter, out bool rangeRequired) { rangeRequired = false; // check filter. DataChangeFilter datachangeFilter = null; if (filter != null) { datachangeFilter = filter.Body as DataChangeFilter; } if (datachangeFilter != null) { // get the datatype of the node. NodeId datatypeId = metadata.DataType; // check that filter is valid. ServiceResult error = datachangeFilter.Validate(); if (ServiceResult.IsBad(error)) { return error; } // check datatype of the variable. if (!m_server.TypeTree.IsTypeOf(datatypeId, DataTypes.Number)) { return StatusCodes.BadDeadbandFilterInvalid; } // percent deadbands only allowed for analog data items. if (datachangeFilter.DeadbandType == (uint)(int)DeadbandType.Percent) { ExpandedNodeId typeDefinitionId = metadata.TypeDefinition; if (typeDefinitionId == null) { return StatusCodes.BadDeadbandFilterInvalid; } // percent deadbands only allowed for analog data items. if (!m_server.TypeTree.IsTypeOf(typeDefinitionId, VariableTypes.AnalogItemType)) { return StatusCodes.BadDeadbandFilterInvalid; } // the EURange property is required to use the filter. rangeRequired = true; } } // filter is valid return ServiceResult.Good; }
/// <summary> /// Returns the basic metadata for the node. Returns null if the node does not exist. /// </summary> /// <remarks> /// This method validates any placeholder handle. /// </remarks> public virtual NodeMetadata GetNodeMetadata( OperationContext context, object targetHandle, BrowseResultMask resultMask) { ServerSystemContext systemContext = m_systemContext.Copy(context); lock (Lock) { // check for valid handle. NodeState target = IsHandleInNamespace(targetHandle); if (target == null) { return null; } // validate node. if (!ValidateNode(systemContext, target)) { return null; } // read the attributes. List<object> values = target.ReadAttributes( systemContext, Attributes.WriteMask, Attributes.UserWriteMask, Attributes.DataType, Attributes.ValueRank, Attributes.ArrayDimensions, Attributes.AccessLevel, Attributes.UserAccessLevel, Attributes.EventNotifier, Attributes.Executable, Attributes.UserExecutable); // construct the metadata object. NodeMetadata metadata = new NodeMetadata(target, target.NodeId); metadata.NodeClass = target.NodeClass; metadata.BrowseName = target.BrowseName; metadata.DisplayName = target.DisplayName; if (values[0] != null && values[1] != null) { metadata.WriteMask = (AttributeWriteMask)(((uint)values[0]) & ((uint)values[1])); } metadata.DataType = (NodeId)values[2]; if (values[3] != null) { metadata.ValueRank = (int)values[3]; } metadata.ArrayDimensions = (IList<uint>)values[4]; if (values[5] != null && values[6] != null) { metadata.AccessLevel = (byte)(((byte)values[5]) & ((byte)values[6])); } if (values[7] != null) { metadata.EventNotifier = (byte)values[7]; } if (values[8] != null && values[9] != null) { metadata.Executable = (((bool)values[8]) && ((bool)values[9])); } // get instance references. BaseInstanceState instance = target as BaseInstanceState; if (instance != null) { metadata.TypeDefinition = instance.TypeDefinitionId; metadata.ModellingRule = instance.ModellingRuleId; } // fill in the common attributes. return metadata; } }
/// <see cref="INodeManager.GetNodeMetadata" /> public NodeMetadata GetNodeMetadata( OperationContext context, object targetHandle, BrowseResultMask resultMask) { if (context == null) throw new ArgumentNullException("context"); // find target. ILocalNode target = targetHandle as ILocalNode; if (target == null) { return null; } lock (m_lock) { // copy the default metadata. NodeMetadata metadata = new NodeMetadata(target, target.NodeId); // copy target attributes. if ((resultMask & BrowseResultMask.NodeClass) != 0) { metadata.NodeClass = (NodeClass)target.NodeClass; } if ((resultMask & BrowseResultMask.BrowseName) != 0) { metadata.BrowseName = target.BrowseName; } if ((resultMask & BrowseResultMask.DisplayName) != 0) { metadata.DisplayName = target.DisplayName; // check if the display name can be localized. if (!String.IsNullOrEmpty(metadata.DisplayName.Key)) { metadata.DisplayName = Server.ResourceManager.Translate(context.PreferredLocales, metadata.DisplayName); } } metadata.WriteMask = target.WriteMask; if (metadata.WriteMask != AttributeWriteMask.None) { DataValue value = new DataValue((uint)(int)target.UserWriteMask); ServiceResult result = target.Read(context, Attributes.UserWriteMask, value); if (ServiceResult.IsBad(result)) { metadata.WriteMask = AttributeWriteMask.None; } else { metadata.WriteMask = (AttributeWriteMask)(int)((uint)(int)metadata.WriteMask & (uint)value.Value); } } metadata.EventNotifier = EventNotifiers.None; metadata.AccessLevel = AccessLevels.None; metadata.Executable = false; switch (target.NodeClass) { case NodeClass.Object: { metadata.EventNotifier = ((IObject)target).EventNotifier; break; } case NodeClass.View: { metadata.EventNotifier = ((IView)target).EventNotifier; break; } case NodeClass.Variable: { IVariable variable = (IVariable)target; metadata.DataType = variable.DataType; metadata.ValueRank = variable.ValueRank; metadata.ArrayDimensions = variable.ArrayDimensions; metadata.AccessLevel = variable.AccessLevel; DataValue value = new DataValue(variable.UserAccessLevel); ServiceResult result = variable.Read(context, Attributes.UserAccessLevel, value); if (ServiceResult.IsBad(result)) { metadata.AccessLevel = 0; break; } metadata.AccessLevel = (byte)(metadata.AccessLevel & (byte)value.Value); break; } case NodeClass.Method: { IMethod method = (IMethod)target; metadata.Executable = method.Executable; if (metadata.Executable) { DataValue value = new DataValue(method.UserExecutable); ServiceResult result = method.Read(context, Attributes.UserExecutable, value); if (ServiceResult.IsBad(result)) { metadata.Executable = false; break; } metadata.Executable = (bool)value.Value; } break; } } // look up type definition. if ((resultMask & BrowseResultMask.TypeDefinition) != 0) { if (target.NodeClass == NodeClass.Variable || target.NodeClass == NodeClass.Object) { metadata.TypeDefinition = target.TypeDefinitionId; } } #if LEGACY_NODEMANAGER // check if a source is defined for the node. SourceHandle handle = target.Handle as SourceHandle; if (handle != null) { // check if the metadata needs to be updated by the source. IReadMetadataSource source = handle.Source as IReadMetadataSource; if (source != null) { source.ReadMetadata( context, handle.Handle, resultMask, metadata); } } #endif // return metadata. return metadata; } }