Example #1
0
        /// <summary>
        /// Validates the nodes and writes the value to the underlying system.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="nodesToWrite">The nodes to write.</param>
        /// <param name="errors">The errors.</param>
        /// <param name="nodesToValidate">The nodes to validate.</param>
        /// <param name="cache">The cache.</param>
        protected override void Write(
            ServerSystemContext context,
            IList <WriteValue> nodesToWrite,
            IList <ServiceResult> errors,
            List <NodeHandle> nodesToValidate,
            IDictionary <NodeId, NodeState> cache)
        {
            ComDaClientManager system = (ComDaClientManager)this.SystemContext.SystemHandle;
            ComDaClient        client = system.SelectClient((ServerSystemContext)SystemContext, false);

            WriteRequestCollection requests = new WriteRequestCollection();

            // validates the nodes and queues an write requests.
            for (int ii = 0; ii < nodesToValidate.Count; ii++)
            {
                NodeHandle handle = nodesToValidate[ii];

                lock (Lock)
                {
                    // validate node.
                    NodeState source = ValidateNode(context, handle, cache);

                    if (source == null)
                    {
                        continue;
                    }

                    // determine if request can be sent to the server.
                    bool       queued      = false;
                    WriteValue nodeToWrite = nodesToWrite[handle.Index];
                    errors[handle.Index] = requests.Add(source, nodeToWrite, handle.Index, out queued);

                    if (queued)
                    {
                        continue;
                    }

                    // write the attribute value.
                    errors[handle.Index] = source.WriteAttribute(
                        context,
                        nodeToWrite.AttributeId,
                        nodeToWrite.ParsedIndexRange,
                        nodeToWrite.Value);

                    // updates to source finished - report changes to monitored items.
                    source.ClearChangeMasks(context, false);
                }
            }

            // write to the server.
            client.Write(requests);

            // get the results from the requests sent to the server.
            for (int ii = 0; ii < requests.Count; ii++)
            {
                WriteRequest request = requests[ii];
                errors[request.Index] = request.GetResult();
            }
        }
Example #2
0
        private ServiceResult OnWriteValueDiscrete(
            ISystemContext context,
            NodeState node,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            ref object value,
            ref StatusCode statusCode,
            ref DateTime timestamp)
        {
            MultiStateValueDiscreteState variable = node as MultiStateValueDiscreteState;

            TypeInfo typeInfo = TypeInfo.Construct(value);

            if (variable == null ||
                typeInfo == null ||
                typeInfo == Opc.Ua.TypeInfo.Unknown ||
                !TypeInfo.IsNumericType(typeInfo.BuiltInType))
            {
                return(StatusCodes.BadTypeMismatch);
            }

            if (indexRange != NumericRange.Empty)
            {
                return(StatusCodes.BadIndexRangeInvalid);
            }

            Int32 number = Convert.ToInt32(value);

            if (number >= variable.EnumValues.Value.Length || number < 0)
            {
                return(StatusCodes.BadOutOfRange);
            }

            if (!node.SetChildValue(context, BrowseNames.ValueAsText, variable.EnumValues.Value[number].DisplayName,
                                    true))
            {
                return(StatusCodes.BadOutOfRange);
            }

            node.ClearChangeMasks(context, true);

            return(ServiceResult.Good);
        }
        /// <summary>
        /// Recursively indexes the node and its children.
        /// </summary>
        protected virtual void RemovePredefinedNode(
            ISystemContext context, 
            NodeState node, 
            List<LocalReference> referencesToRemove)
        {
            m_predefinedNodes.Remove(node.NodeId);
            node.UpdateChangeMasks(NodeStateChangeMasks.Deleted);
            node.ClearChangeMasks(context, false);
            OnNodeRemoved(node);

            // remove from the parent.
            BaseInstanceState instance = node as BaseInstanceState;

            if (instance != null && instance.Parent != null)
            {
                instance.Parent.RemoveChild(instance);
            }

            // remove children.
            List<BaseInstanceState> children = new List<BaseInstanceState>();
            node.GetChildren(context, children);

            for (int ii = 0; ii < children.Count; ii++)
            {
                node.RemoveChild(children[ii]);
            }

            for (int ii = 0; ii < children.Count; ii++)
            {
                RemovePredefinedNode(context, children[ii], referencesToRemove);
            }
                        
            // remove from type table.
            BaseTypeState type = node as BaseTypeState;

            if (type != null)
            {
                m_server.TypeTree.Remove(type.NodeId);
            }
            
            // remove inverse references.
            List<IReference> references = new List<IReference>();
            node.GetReferences(context, references);

            for (int ii = 0; ii < references.Count; ii++)
            {
                IReference reference = references[ii];

                if (reference.TargetId.IsAbsolute)
                {
                    continue;
                }

                LocalReference referenceToRemove = new LocalReference(
                    (NodeId)reference.TargetId,
                    reference.ReferenceTypeId,
                    reference.IsInverse,
                    node.NodeId);

                referencesToRemove.Add(referenceToRemove);
            }
        }
        /// <summary>
        /// Handles a write operation.
        /// </summary>
        protected override void Write(
            ServerSystemContext context,
            IList <WriteValue> nodesToWrite,
            IList <ServiceResult> errors,
            List <NodeHandle> nodesToValidate,
            IDictionary <NodeId, NodeState> cache)
        {
            List <ReadWriteRequest> requests = new List <ReadWriteRequest>();

            // validates the nodes and constructs requests for external nodes.
            for (int ii = 0; ii < nodesToValidate.Count; ii++)
            {
                WriteValue nodeToWrite = nodesToWrite[ii];
                NodeHandle handle      = nodesToValidate[ii];

                lock (Lock)
                {
                    // validate node.
                    NodeState source = ValidateNode(context, handle, cache);

                    if (source == null)
                    {
                        continue;
                    }

                    // determine if an external source is required.
                    if (IsExternalSource(handle, nodeToWrite.AttributeId))
                    {
                        errors[handle.Index] = AddWriteRequest(context, handle, nodeToWrite, requests);
                        continue;
                    }

                    // write the attribute value.
                    errors[handle.Index] = source.WriteAttribute(
                        context,
                        nodeToWrite.AttributeId,
                        nodeToWrite.ParsedIndexRange,
                        nodeToWrite.Value);

                    // updates to source finished - report changes to monitored items.
                    source.ClearChangeMasks(context, false);
                }
            }

            // send request to external system.
            try
            {
                ProcessWriteRequests(requests);
            }
            catch (Exception e)
            {
                // handle unexpected communication error.
                ServiceResult error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not access external system.");

                for (int ii = 0; ii < requests.Count; ii++)
                {
                    requests[ii].Result = error;
                }
            }

            // set results.
            for (int ii = 0; ii < requests.Count; ii++)
            {
                ReadWriteRequest request = requests[ii];
                errors[request.Handle.Index] = request.Result;
            }
        }