Ejemplo n.º 1
0
 public void Execute(MethodDefinition method)
 {
     ExecutionEngine engine = new ExecutionEngine();
     Thread thread = new Thread(engine);
     MethodState state = new MethodState(thread, method);
     thread.Methods.Push(state);
     thread.Execute();
 }
Ejemplo n.º 2
0
 public void Execute(MethodState state, Instruction inst)
 {
     // FIXME SECURITY: Verifier should ensure all ldloc access is under the local var max.
     if (this.m_Parameter == null)
         state.LocalVariables[(int)inst.Operand] = state.EvaluationStack.Pop();
     else
         state.LocalVariables[(int)this.m_Parameter] = state.EvaluationStack.Pop();
 }
Ejemplo n.º 3
0
		public EditedMethodUpdater(Lazy<IMethodAnnotations> methodAnnotations, ModuleDocumentNode modNode, MethodDef originalMethod, Emit.MethodBody newBody, MethodDefOptions methodDefOptions) {
			this.methodAnnotations = methodAnnotations;
			ownerNode = modNode.Context.DocumentTreeView.FindNode(originalMethod);
			if (ownerNode == null)
				throw new InvalidOperationException();
			method = originalMethod;
			originalMethodState = new MethodState(originalMethod, methodAnnotations.Value.IsBodyModified(method));
			newMethodState = new MethodState(newBody, methodDefOptions, true);
		}
Ejemplo n.º 4
0
 public void Execute(MethodState state, Instruction inst)
 {
     if (inst.Operand is MemberReference)
     {
         if ((inst.Operand as MemberReference).FullName == "System.Void System.Console::WriteLine(System.String)")
             Console.WriteLine((string)state.EvaluationStack.Pop());
         else
             throw new NotSupportedException();
     }
     else
         throw new NotSupportedException();
 }
Ejemplo n.º 5
0
		public void VisitMethod(BeginMethod begin)
		{
			if (!m_disabled)
			{
				Log.DebugLine(this, "{0}", begin.Info.Method);	
								
				string root = DoGetRootName(begin.Info.Method);
				MethodState state = new MethodState
				{
					Method = begin.Info.Method,
					IsThreadRoot = root != null,
					IsThreadSafe = DoIsMarkedThreadSafe(begin.Info.Method),
					IsExternal = begin.Info.Method.ExternallyVisible(Cache),
				};
				m_methods.Add(begin.Info.Method, state);
				
				if (root != null)
				{
					m_knownRoots.Add(state, root);
				}
				else if (state.IsThreadSafe && state.IsExternal)
				{
					m_knownRoots.Add(state, "*");
				}
				else
				{
					if (Cache.Assembly.EntryPoint == begin.Info.Method)
					{
						m_entryPoints.Add(begin.Info.Method);
					}
					else if (state.IsExternal)
					{
						Log.TraceLine(this, "Externally visible but not marked as a thread:");
						Log.TraceLine(this, "   {0}", begin.Info.Method);
						m_entryPoints.Add(begin.Info.Method);
					}
				}
				
				if (DoTypeIsMarkedThreadSafe(begin.Info.Type))
					if (m_safeTypes.IndexOf(begin.Info.Type) < 0)
						m_safeTypes.Add(begin.Info.Type);
				
				if (DoMethodIsMarkedThreadSafe(begin.Info.Method))
					m_safeMethods.Add(state);
			}
		}
Ejemplo n.º 6
0
 public void Execute(MethodState state, Instruction inst)
 {
     switch (this.m_Type)
     {
         case LdcType.i4:
             if (this.m_Parameter == null)
                 state.EvaluationStack.Push(new Int32Type((Int32)inst.Operand));
             else
                 state.EvaluationStack.Push(new Int32Type((Int32)this.m_Parameter));
             break;
         case LdcType.i8:
             state.EvaluationStack.Push(new Int64Type((Int64)inst.Operand));
             break;
         case LdcType.r4:
         case LdcType.r8:
             state.EvaluationStack.Push(new FloatingPointType((float)inst.Operand));
             break;
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return null;
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
                case ObjectTypeTest.BrowseNames.BrowseName4node66:
                {
                    if (createOrReplace)
                    {
                        if (BrowseName4node66 == null)
                        {
                            if (replacement == null)
                            {
                                BrowseName4node66 = new PropertyState<LocalizedText>(this);
                            }
                            else
                            {
                                BrowseName4node66 = (PropertyState<LocalizedText>)replacement;
                            }
                        }
                    }

                    instance = BrowseName4node66;
                    break;
                }

                case ObjectTypeTest.BrowseNames.NameNotSet1109:
                {
                    if (createOrReplace)
                    {
                        if (NameNotSet1109 == null)
                        {
                            if (replacement == null)
                            {
                                NameNotSet1109 = new AnalogItemState(this);
                            }
                            else
                            {
                                NameNotSet1109 = (AnalogItemState)replacement;
                            }
                        }
                    }

                    instance = NameNotSet1109;
                    break;
                }

                case ObjectTypeTest.BrowseNames.ChildMethod:
                {
                    if (createOrReplace)
                    {
                        if (ChildMethod == null)
                        {
                            if (replacement == null)
                            {
                                ChildMethod = new ChildMethodComplexObjectMethodState(this);
                            }
                            else
                            {
                                ChildMethod = (ChildMethodComplexObjectMethodState)replacement;
                            }
                        }
                    }

                    instance = ChildMethod;
                    break;
                }

                case ObjectTypeTest.BrowseNames.NonExecutableMethod:
                {
                    if (createOrReplace)
                    {
                        if (NonExecutableMethod == null)
                        {
                            if (replacement == null)
                            {
                                NonExecutableMethod = new MethodState(this);
                            }
                            else
                            {
                                NonExecutableMethod = (MethodState)replacement;
                            }
                        }
                    }

                    instance = NonExecutableMethod;
                    break;
                }
            }

            if (instance != null)
            {
                return instance;
            }

            return base.FindChild(context, browseName, createOrReplace, replacement);
        }
Ejemplo n.º 8
0
        private ServiceResult CloseAndUpdate(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            uint fileHandle,
            ref bool restartRequired)
        {
            HasSecureWriteAccess(context);

            ServiceResult result = StatusCodes.Good;

            lock (m_lock)
            {
                if (m_sessionId != context.SessionId)
                {
                    return(StatusCodes.BadUserAccessDenied);
                }

                if (m_fileHandle != fileHandle)
                {
                    return(StatusCodes.BadInvalidArgument);
                }

                try
                {
                    TrustListDataType trustList = DecodeTrustListData(context, m_strm);
                    TrustListMasks    masks     = (TrustListMasks)trustList.SpecifiedLists;

                    X509Certificate2Collection issuerCertificates  = null;
                    List <X509CRL>             issuerCrls          = null;
                    X509Certificate2Collection trustedCertificates = null;
                    List <X509CRL>             trustedCrls         = null;

                    // test integrity of all CRLs
                    if ((masks & TrustListMasks.IssuerCertificates) != 0)
                    {
                        issuerCertificates = new X509Certificate2Collection();
                        foreach (var cert in trustList.IssuerCertificates)
                        {
                            issuerCertificates.Add(new X509Certificate2(cert));
                        }
                    }
                    if ((masks & TrustListMasks.IssuerCrls) != 0)
                    {
                        issuerCrls = new List <X509CRL>();
                        foreach (var crl in trustList.IssuerCrls)
                        {
                            issuerCrls.Add(new X509CRL(crl));
                        }
                    }
                    if ((masks & TrustListMasks.TrustedCertificates) != 0)
                    {
                        trustedCertificates = new X509Certificate2Collection();
                        foreach (var cert in trustList.TrustedCertificates)
                        {
                            trustedCertificates.Add(new X509Certificate2(cert));
                        }
                    }
                    if ((masks & TrustListMasks.TrustedCrls) != 0)
                    {
                        trustedCrls = new List <X509CRL>();
                        foreach (var crl in trustList.TrustedCrls)
                        {
                            trustedCrls.Add(new X509CRL(crl));
                        }
                    }

                    // update store
                    // test integrity of all CRLs
                    TrustListMasks updateMasks = TrustListMasks.None;
                    if ((masks & TrustListMasks.IssuerCertificates) != 0)
                    {
                        if (UpdateStoreCertificates(m_issuerStorePath, issuerCertificates))
                        {
                            updateMasks |= TrustListMasks.IssuerCertificates;
                        }
                    }
                    if ((masks & TrustListMasks.IssuerCrls) != 0)
                    {
                        if (UpdateStoreCrls(m_issuerStorePath, issuerCrls))
                        {
                            updateMasks |= TrustListMasks.IssuerCrls;
                        }
                    }
                    if ((masks & TrustListMasks.TrustedCertificates) != 0)
                    {
                        if (UpdateStoreCertificates(m_trustedStorePath, trustedCertificates))
                        {
                            updateMasks |= TrustListMasks.TrustedCertificates;
                        }
                    }
                    if ((masks & TrustListMasks.TrustedCrls) != 0)
                    {
                        if (UpdateStoreCrls(m_trustedStorePath, trustedCrls))
                        {
                            updateMasks |= TrustListMasks.TrustedCrls;
                        }
                    }

                    if (masks != updateMasks)
                    {
                        result = StatusCodes.BadCertificateInvalid;
                    }
                }
                catch
                {
                    result = StatusCodes.BadCertificateInvalid;
                }
                finally
                {
                    m_sessionId = null;
                    m_strm      = null;
                    m_node.LastUpdateTime.Value = DateTime.UtcNow;
                    m_node.OpenCount.Value      = 0;
                }
            }

            restartRequired = false;

            return(result);
        }
        private ServiceResult ApplyChanges(
            ISystemContext context,
            MethodState method,
            IList <object> inputArguments,
            IList <object> outputArguments)
        {
            HasApplicationSecureAdminAccess(context);

            bool disconnectSessions = false;

            foreach (var certificateGroup in m_certificateGroups)
            {
                try
                {
                    var updateCertificate = certificateGroup.UpdateCertificate;
                    if (updateCertificate != null)
                    {
                        if (certificateGroup.UpdateCertificate.SessionId == context.SessionId)
                        {
                            using (ICertificateStore appStore = CertificateStoreIdentifier.OpenStore(certificateGroup.ApplicationCertificate.StorePath))
                            {
                                appStore.Delete(certificateGroup.ApplicationCertificate.Thumbprint).Wait();
                                appStore.Add(updateCertificate.CertificateWithPrivateKey).Wait();
                                updateCertificate.CertificateWithPrivateKey = null;
                            }
                            using (ICertificateStore issuerStore = CertificateStoreIdentifier.OpenStore(certificateGroup.IssuerStorePath))
                            {
                                foreach (var issuer in updateCertificate.IssuerCollection)
                                {
                                    try
                                    {
                                        issuerStore.Add(issuer).Wait();
                                    }
                                    catch (ArgumentException)
                                    {
                                        // ignore error if issuer cert already exists
                                    }
                                }
                            }

                            disconnectSessions = true;
                        }
                    }
                }
                finally
                {
                    certificateGroup.UpdateCertificate = null;
                }
            }

            if (disconnectSessions)
            {
                Task.Run(async() =>
                {
                    // give the client some time to receive the response
                    // before the certificate update may disconnect all sessions
                    await Task.Delay(1000);
                    await m_configuration.CertificateValidator.UpdateCertificate(m_configuration.SecurityConfiguration);
                }
                         );
            }

            return(StatusCodes.Good);
        }
        /// <summary>
        /// Method to remove the node from the subscription and stop publishing telemetry to IoTHub. Executes synchronously.
        /// </summary>
        private ServiceResult OnUnpublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string))
            {
                Trace("UnpublishNode: Invalid arguments!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!"));
            }

            bool           result         = false;
            NodeId         nodeId         = null;
            ExpandedNodeId expandedNodeId = null;
            Uri            endpointUri    = null;
            bool           isNodeIdFormat = true;

            try
            {
                string id = inputArguments[0] as string;
                if (id.Contains("nsu="))
                {
                    expandedNodeId = ExpandedNodeId.Parse(id);
                    isNodeIdFormat = false;
                }
                else
                {
                    nodeId         = NodeId.Parse(id);
                    isNodeIdFormat = true;
                }
                endpointUri = new Uri(inputArguments[1] as string);
            }
            catch (UriFormatException)
            {
                Trace($"UnpublishNode: The endpointUrl is invalid '{inputArguments[1] as string}'!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }
            catch (Exception e)
            {
                Trace(e, $"UnpublishNode: The NodeId has an invalid format '{inputArguments[0] as string}'!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in NodeId or ExpandedNodeId format as first argument!"));
            }

            // find the session and stop monitoring the node.
            try
            {
                if (ShutdownTokenSource.IsCancellationRequested)
                {
                    return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress."));
                }

                // find the session we need to monitor the node
                OpcSession opcSession = null;
                try
                {
                    OpcSessionsListSemaphore.Wait();
                    opcSession = OpcSessions.FirstOrDefault(s => s.EndpointUri.AbsoluteUri.Equals(endpointUri.AbsoluteUri, StringComparison.OrdinalIgnoreCase));
                }
                catch
                {
                    opcSession = null;
                }
                finally
                {
                    OpcSessionsListSemaphore.Release();
                }

                if (opcSession == null)
                {
                    // do nothing if there is no session for this endpoint.
                    Trace($"UnpublishNode: Session for endpoint '{endpointUri.OriginalString}' not found.");
                    return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for endpoint of node to unpublished not found!"));
                }
                else
                {
                    if (isNodeIdFormat)
                    {
                        // stop monitoring the node, execute syncronously
                        Trace($"UnpublishNode: Request to stop monitoring item with NodeId '{nodeId.ToString()}' (PublishingInterval: {OpcPublishingInterval}, SamplingInterval: {OpcSamplingInterval})");
                        result = opcSession.RequestMonitorItemRemovalAsync(nodeId, null, OpcPublishingInterval, OpcSamplingInterval, ShutdownTokenSource.Token).Result;
                    }
                    else
                    {
                        // stop monitoring the node, execute syncronously
                        Trace($"UnpublishNode: Request to stop monitoring item with ExpandedNodeId '{expandedNodeId.ToString()}' (PublishingInterval: {OpcPublishingInterval}, SamplingInterval: {OpcSamplingInterval})");
                        result = opcSession.RequestMonitorItemRemovalAsync(null, expandedNodeId, OpcPublishingInterval, OpcSamplingInterval, ShutdownTokenSource.Token).Result;
                    }
                }
            }
            catch (Exception e)
            {
                Trace(e, $"UnpublishNode: Exception while trying to configure publishing node '{nodeId.ToString()}'");
                return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error unpublishing node: {e.Message}"));
            }
            return(result ? ServiceResult.Good : ServiceResult.Create(StatusCodes.Bad, "Can not stop monitoring node!"));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Called when a client locks the server.
        /// </summary>
        public ServiceResult OnGetMonitoredItems(
            ISystemContext context,
            MethodState method,
            IList<object> inputArguments,
            IList<object> outputArguments)
        {
            if (inputArguments == null || inputArguments.Count != 1)
            {
                return StatusCodes.BadInvalidArgument;
            }

            uint? subscriptionId = inputArguments[0] as uint?;

            if (subscriptionId == null)
            {
                return StatusCodes.BadInvalidArgument;
            }

            uint[] serverHandles = null;
            uint[] clientHandles = null;

            foreach (Subscription subscription in Server.SubscriptionManager.GetSubscriptions())
            {
                if (subscription.Id == subscriptionId)
                {
                    subscription.GetMonitoredItems(out serverHandles, out clientHandles);

                    outputArguments[0] = serverHandles;
                    outputArguments[1] = clientHandles;

                    return ServiceResult.Good;
                }
            }

            return StatusCodes.BadSubscriptionIdInvalid;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Method exposed as a node in the server to stop monitoring it and no longer publish telemetry of it.
        /// </summary>
        private ServiceResult UnPublishNodeMethod(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (inputArguments[0] == null || inputArguments[1] == null)
            {
                Trace("UnPublishNodeMethod: Invalid arguments!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!"));
            }

            string nodeId      = inputArguments[0] as string;
            string endpointUrl = inputArguments[1] as string;

            if (string.IsNullOrEmpty(nodeId) || string.IsNullOrEmpty(endpointUrl))
            {
                Trace($"UnPublishNodeMethod: Arguments (0 (nodeId): '{nodeId}', 1 (endpointUrl):'{endpointUrl}') are not valid strings!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            NodeToPublish nodeToUnpublish = new NodeToPublish();

            try
            {
                nodeToUnpublish = new NodeToPublish(nodeId, endpointUrl);
            }
            catch (UriFormatException)
            {
                Trace($"UnPublishNodeMethod: The endpointUrl is invalid (0 (nodeId): '{nodeId}', 1 (endpointUrl):'{endpointUrl}')!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }

            // Find the session and stop monitoring the node.
            try
            {
                // find the session we need to monitor the node
                OpcSession opcSession = OpcSessions.First(s => s.EndpointUri == nodeToUnpublish.EndPointUri);
                if (opcSession == null)
                {
                    // do nothing if there is no session for this endpoint.
                    Trace($"UnPublishNodeMethod: Session for endpoint '{nodeToUnpublish.EndPointUri.AbsolutePath}' not found.");
                    return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for endpoint of published node not found!"));
                }
                else
                {
                    Trace($"UnPublishNodeMethod: Session found for endpoint '{nodeToUnpublish.EndPointUri.AbsolutePath}'");
                }

                // remove the node from the sessions monitored items list.
                opcSession.TagNodeForMonitoringStop(nodeToUnpublish.NodeId);
                Trace("UnPublishNodeMethod: Requested to stop monitoring of node.");

                // stop monitoring the node
                Task monitorTask = Task.Run(async() => await opcSession.ConnectAndMonitor());
                monitorTask.Wait();
                Trace("UnPublishNodeMethod: Session processing completed.");

                // remove node from our persisted data set.
                var itemToRemove = NodesToPublish.Find(l => l.NodeId == nodeToUnpublish.NodeId && l.EndPointUri == nodeToUnpublish.EndPointUri);
                NodesToPublish.Remove(itemToRemove);

                // persist data
                File.WriteAllText(NodesToPublishAbsFilename, JsonConvert.SerializeObject(NodesToPublish));
            }
            catch (Exception e)
            {
                Trace(e, $"DoPublish: Exception while trying to configure publishing node '{nodeToUnpublish.ToString()}'");
                return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}"));
            }
            return(ServiceResult.Good);
        }
Ejemplo n.º 13
0
 public abstract void SetNode(MethodState node);
Ejemplo n.º 14
0
        /// <summary>
        /// Imports a node from the set.
        /// </summary>
        private NodeState Import(ISystemContext context, UANode node)
        {
            NodeState importedNode = null;

            NodeClass nodeClass = NodeClass.Unspecified;

            if (node is UAObject) nodeClass = NodeClass.Object;
            else if (node is UAVariable) nodeClass = NodeClass.Variable;
            else if (node is UAMethod) nodeClass = NodeClass.Method;
            else if (node is UAObjectType) nodeClass = NodeClass.ObjectType;
            else if (node is UAVariableType) nodeClass = NodeClass.VariableType;
            else if (node is UADataType) nodeClass = NodeClass.DataType;
            else if (node is UAReferenceType) nodeClass = NodeClass.ReferenceType;
            else if (node is UAView) nodeClass = NodeClass.View;

            switch (nodeClass)
            {
                case NodeClass.Object:
                {
                    UAObject o = (UAObject)node;
                    BaseObjectState value = new BaseObjectState(null);
                    value.EventNotifier = o.EventNotifier;
                    importedNode = value;
                    break;
                }

                case NodeClass.Variable:
                {
                    UAVariable o = (UAVariable)node;

                    NodeId typeDefinitionId = null;

                    if (node.References != null)
                    {
                        for (int ii = 0; ii < node.References.Length; ii++)
                        {
                            Opc.Ua.NodeId referenceTypeId = ImportNodeId(node.References[ii].ReferenceType, context.NamespaceUris, true);
                            bool isInverse = !node.References[ii].IsForward;
                            Opc.Ua.ExpandedNodeId targetId = ImportExpandedNodeId(node.References[ii].Value, context.NamespaceUris, context.ServerUris);

                            if (referenceTypeId == ReferenceTypeIds.HasTypeDefinition && !isInverse)
                            {
                                typeDefinitionId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                                break;
                            }
                        }
                    }

                    BaseVariableState value = null;

                    if (typeDefinitionId == Opc.Ua.VariableTypeIds.PropertyType)
                    {
                        value = new PropertyState(null);
                    }
                    else
                    {
                        value = new BaseDataVariableState(null);
                    }

                    value.DataType = ImportNodeId(o.DataType, context.NamespaceUris, true);
                    value.ValueRank = o.ValueRank;
                    value.ArrayDimensions = ImportArrayDimensions(o.ArrayDimensions);
                    value.AccessLevel = o.AccessLevel;
                    value.UserAccessLevel = o.UserAccessLevel;
                    value.MinimumSamplingInterval = o.MinimumSamplingInterval;
                    value.Historizing = o.Historizing;

                    if (o.Value != null)
                    {
                        XmlDecoder decoder = CreateDecoder(context, o.Value);
                        TypeInfo typeInfo = null;
                        value.Value = decoder.ReadVariantContents(out typeInfo);
                        decoder.Close();
                    }

                    importedNode = value;
                    break;
                }

                case NodeClass.Method:
                {
                    UAMethod o = (UAMethod)node;
                    MethodState value = new MethodState(null);
                    value.Executable = o.Executable;
                    value.UserExecutable = o.UserExecutable;
                    importedNode = value;
                    break;
                }

                case NodeClass.View:
                {
                    UAView o = (UAView)node;
                    ViewState value = new ViewState();
                    value.ContainsNoLoops = o.ContainsNoLoops;
                    importedNode = value;
                    break;
                }

                case NodeClass.ObjectType:
                {
                    UAObjectType o = (UAObjectType)node;
                    BaseObjectTypeState value = new BaseObjectTypeState();
                    value.IsAbstract = o.IsAbstract;
                    importedNode = value;
                    break;
                }

                case NodeClass.VariableType:
                {
                    UAVariableType o = (UAVariableType)node;
                    BaseVariableTypeState value = new BaseDataVariableTypeState();
                    value.IsAbstract = o.IsAbstract;
                    value.DataType = ImportNodeId(o.DataType, context.NamespaceUris, true);
                    value.ValueRank = o.ValueRank;
                    value.ArrayDimensions = ImportArrayDimensions(o.ArrayDimensions);

                    if (o.Value != null)
                    {
                        XmlDecoder decoder = CreateDecoder(context, o.Value);
                        TypeInfo typeInfo = null;
                        value.Value = decoder.ReadVariantContents(out typeInfo);
                        decoder.Close();
                    }

                    importedNode = value;
                    break;
                }

                case NodeClass.DataType:
                {
                    UADataType o = (UADataType)node;
                    DataTypeState value = new DataTypeState();
                    value.IsAbstract = o.IsAbstract;
                    value.Definition = Import(o.Definition, context.NamespaceUris);
                    importedNode = value;
                    break;
                }

                case NodeClass.ReferenceType:
                {
                    UAReferenceType o = (UAReferenceType)node;
                    ReferenceTypeState value = new ReferenceTypeState();
                    value.IsAbstract = o.IsAbstract;
                    value.InverseName = Import(o.InverseName);
                    value.Symmetric = o.Symmetric;
                    importedNode = value;
                    break;
                }
            }

            importedNode.NodeId = ImportNodeId(node.NodeId, context.NamespaceUris, false);
            importedNode.BrowseName = ImportQualifiedName(node.BrowseName, context.NamespaceUris);
            importedNode.DisplayName = Import(node.DisplayName);
            importedNode.Description = Import(node.Description);
            importedNode.WriteMask = (AttributeWriteMask)node.WriteMask;
            importedNode.UserWriteMask = (AttributeWriteMask)node.UserWriteMask;

            if (!String.IsNullOrEmpty(node.SymbolicName))
            {
                importedNode.SymbolicName = node.SymbolicName;
            }

            if (node.References != null)
            {
                BaseInstanceState instance = importedNode as BaseInstanceState;
                BaseTypeState type = importedNode as BaseTypeState;

                for (int ii = 0; ii < node.References.Length; ii++)
                {
                    Opc.Ua.NodeId referenceTypeId = ImportNodeId(node.References[ii].ReferenceType, context.NamespaceUris, true);
                    bool isInverse = !node.References[ii].IsForward;
                    Opc.Ua.ExpandedNodeId targetId = ImportExpandedNodeId(node.References[ii].Value, context.NamespaceUris, context.ServerUris);

                    if (instance != null)
                    {
                        if (referenceTypeId == ReferenceTypeIds.HasModellingRule && !isInverse)
                        {
                            instance.ModellingRuleId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            continue;
                        }

                        if (referenceTypeId == ReferenceTypeIds.HasTypeDefinition && !isInverse)
                        {
                            instance.TypeDefinitionId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            continue;
                        }
                    }

                    if (type != null)
                    {
                        if (referenceTypeId == ReferenceTypeIds.HasSubtype && isInverse)
                        {
                            type.SuperTypeId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            continue;
                        }
                    }

                    importedNode.AddReference(referenceTypeId, isInverse, targetId);
                }
            }

            return importedNode;
        }
Ejemplo n.º 15
0
 public SwitchOffMethodState(MethodState source) : base(source)
 {
 }
Ejemplo n.º 16
0
 public TCDMethodState(MethodState source) : base(source.Parent)
 {
     Initialize(new SystemContext(), source);
 }
Ejemplo n.º 17
0
 public ResetAllErrorsMethodState(MethodState source) : base(source)
 {
 }
Ejemplo n.º 18
0
 public void Execute(MethodState state, Instruction inst)
 {
     // Does nothing.
 }
Ejemplo n.º 19
0
        /// <summary>
        /// Does any initialization required before the address space can be used.
        /// </summary>
        /// <remarks>
        /// The externalReferences is an out parameter that allows the node manager to link to nodes
        /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
        /// should have a reference to the root folder node(s) exposed by this node manager.
        /// </remarks>
        public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences)
        {
            lock (Lock)
            {
                #region Setup

                IList <IReference> references = null;

                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>();
                }

                #endregion

                try
                {
                    #region Initialize

                    string alarmsName     = "Alarms";
                    string alarmsNodeName = alarmsName;

                    Type   alarmControllerType = Type.GetType("Alarms.AlarmController");
                    int    interval            = 1000;
                    string intervalString      = interval.ToString();

                    int conditionTypeIndex = 0;
                    #endregion

                    #region Create Alarm Folder

                    FolderState alarmsFolder = CreateFolder(null, alarmsNodeName, alarmsName);
                    alarmsFolder.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder);
                    references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, alarmsFolder.NodeId));
                    alarmsFolder.EventNotifier = EventNotifiers.SubscribeToEvents;
                    AddRootNotifier(alarmsFolder);

                    #endregion

                    #region Create Methods
                    string      startMethodName     = "Start";
                    string      startMethodNodeName = alarmsNodeName + "." + startMethodName;
                    MethodState startMethod         = AlarmHelpers.CreateMethod(alarmsFolder, NamespaceIndex, startMethodNodeName, startMethodName);
                    AlarmHelpers.AddStartInputParameters(startMethod, NamespaceIndex);
                    startMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnStart);

                    string      startBranchMethodName     = "StartBranch";
                    string      startBranchMethodNodeName = alarmsNodeName + "." + startBranchMethodName;
                    MethodState startBranchMethod         = AlarmHelpers.CreateMethod(alarmsFolder, NamespaceIndex, startBranchMethodNodeName, startBranchMethodName);
                    AlarmHelpers.AddStartInputParameters(startBranchMethod, NamespaceIndex);
                    startBranchMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnStartBranch);

                    string      endMethodName     = "End";
                    string      endMethodNodeName = alarmsNodeName + "." + endMethodName;
                    MethodState endMethod         = AlarmHelpers.CreateMethod(alarmsFolder, NamespaceIndex, endMethodNodeName, endMethodName);
                    endMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnEnd);
                    #endregion

                    #region Create Variables

                    string analogTriggerName            = "AnalogSource";
                    string analogTriggerNodeName        = alarmsNodeName + "." + analogTriggerName;
                    BaseDataVariableState analogTrigger = AlarmHelpers.CreateVariable(alarmsFolder,
                                                                                      NamespaceIndex, analogTriggerNodeName, analogTriggerName);
                    analogTrigger.OnWriteValue = OnWriteAlarmTrigger;
                    AlarmController  analogAlarmController  = (AlarmController)Activator.CreateInstance(alarmControllerType, analogTrigger, interval, false);
                    SourceController analogSourceController = new SourceController(analogTrigger, analogAlarmController);
                    m_triggerMap.Add("Analog", analogSourceController);

                    string booleanTriggerName            = "BooleanSource";
                    string booleanTriggerNodeName        = alarmsNodeName + "." + booleanTriggerName;
                    BaseDataVariableState booleanTrigger = AlarmHelpers.CreateVariable(alarmsFolder,
                                                                                       NamespaceIndex, booleanTriggerNodeName, booleanTriggerName, boolValue: true);
                    booleanTrigger.OnWriteValue = OnWriteAlarmTrigger;
                    AlarmController  booleanAlarmController  = (AlarmController)Activator.CreateInstance(alarmControllerType, booleanTrigger, interval, true);
                    SourceController booleanSourceController = new SourceController(booleanTrigger, booleanAlarmController);
                    m_triggerMap.Add("Boolean", booleanSourceController);

                    #endregion

                    #region Create Alarms

                    AlarmHolder mandatoryExclusiveLevel = new ExclusiveLevelHolder(
                        this,
                        alarmsFolder,
                        analogSourceController,
                        intervalString,
                        GetSupportedAlarmConditionType(ref conditionTypeIndex),
                        alarmControllerType,
                        interval,
                        optional: false);

                    m_alarms.Add(mandatoryExclusiveLevel.AlarmNodeName, mandatoryExclusiveLevel);

                    AlarmHolder mandatoryNonExclusiveLevel = new NonExclusiveLevelHolder(
                        this,
                        alarmsFolder,
                        analogSourceController,
                        intervalString,
                        GetSupportedAlarmConditionType(ref conditionTypeIndex),
                        alarmControllerType,
                        interval,
                        optional: false);
                    m_alarms.Add(mandatoryNonExclusiveLevel.AlarmNodeName, mandatoryNonExclusiveLevel);

                    AlarmHolder offNormal = new OffNormalAlarmTypeHolder(
                        this,
                        alarmsFolder,
                        booleanSourceController,
                        intervalString,
                        GetSupportedAlarmConditionType(ref conditionTypeIndex),
                        alarmControllerType,
                        interval,
                        optional: false);
                    m_alarms.Add(offNormal.AlarmNodeName, offNormal);


                    #endregion

                    AddPredefinedNode(SystemContext, alarmsFolder);
                    StartTimer();
                    m_allowEntry = true;
                }
                catch (Exception e)
                {
                    Utils.LogError(e, "Error creating the AlarmNodeManager address space.");
                }
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Method exposed as a node in the server to publish a node to IoT Hub that it is connected to
        /// </summary>
        private ServiceResult PublishNodeMethod(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (inputArguments[0] == null || inputArguments[1] == null)
            {
                Trace("PublishNodeMethod: Invalid Arguments!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!"));
            }

            NodeToPublish nodeToPublish;
            string        nodeId      = inputArguments[0] as string;
            string        endpointUrl = inputArguments[1] as string;

            if (string.IsNullOrEmpty(nodeId) || string.IsNullOrEmpty(endpointUrl))
            {
                Trace($"PublishNodeMethod: Arguments (0 (nodeId): '{nodeId}', 1 (endpointUrl):'{endpointUrl}') are not valid strings!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            try
            {
                nodeToPublish = new NodeToPublish(nodeId, endpointUrl);
            }
            catch (UriFormatException)
            {
                Trace($"PublishNodeMethod: The endpointUrl is invalid (0 (nodeId): '{nodeId}', 1 (endpointUrl):'{endpointUrl}')!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }

            // Create session and add item to monitor, what ever is needed.
            try
            {
                // find the session we need to monitor the node
                OpcSession opcSession = OpcSessions.First(s => s.EndpointUri == nodeToPublish.EndPointUri);

                // Add a new session.
                if (opcSession == null)
                {
                    // create new session info.
                    opcSession = new OpcSession(nodeToPublish.EndPointUri, OpcSessionCreationTimeout);
                    OpcSessions.Add(opcSession);
                    Trace($"DoPublish: No matching session found for endpoint '{nodeToPublish.EndPointUri.AbsolutePath}'. Requested to create a new one.");
                }
                else
                {
                    Trace($"DoPublish: Session found for endpoint '{nodeToPublish.EndPointUri.AbsolutePath}'");
                }

                // add the node info to the sessions monitored items list.
                opcSession.AddNodeForMonitoring(nodeToPublish.NodeId);
                Trace("DoPublish: Requested to monitor item.");

                // start monitoring the node
                Task monitorTask = Task.Run(async() => await opcSession.ConnectAndMonitor());
                monitorTask.Wait();
                Trace("DoPublish: Session processing completed.");

                // update our data
                NodesToPublish.Add(nodeToPublish);

                // persist it to disk
                File.WriteAllText(NodesToPublishAbsFilename, JsonConvert.SerializeObject(NodesToPublish));

                Trace($"DoPublish: Now publishing: {nodeToPublish.ToString()}");
                return(ServiceResult.Good);
            }
            catch (Exception e)
            {
                Trace(e, $"DoPublish: Exception while trying to configure publishing node '{nodeToPublish.ToString()}'");
                return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}"));
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Handles a request to refresh conditions for a subscription.
        /// </summary>
        private ServiceResult OnConditionRefresh(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            uint subscriptionId)
        {
            ServerSystemContext systemContext = context as ServerSystemContext;

            if (systemContext == null)
            {
                systemContext = this.SystemContext;
            }

            Server.ConditionRefresh(systemContext.OperationContext, subscriptionId);

            return ServiceResult.Good;
        }
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return(null);
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
            case DataTypeTest.BrowseNames.Name:
            {
                if (createOrReplace)
                {
                    if (Name == null)
                    {
                        if (replacement == null)
                        {
                            Name = new PropertyState <string>(this);
                        }
                        else
                        {
                            Name = (PropertyState <string>)replacement;
                        }
                    }
                }

                instance = Name;
                break;
            }

            case DataTypeTest.BrowseNames.Description:
            {
                if (createOrReplace)
                {
                    if (Description == null)
                    {
                        if (replacement == null)
                        {
                            Description = new PropertyState <string>(this);
                        }
                        else
                        {
                            Description = (PropertyState <string>)replacement;
                        }
                    }
                }

                instance = Description;
                break;
            }

            case DataTypeTest.BrowseNames.Price:
            {
                if (createOrReplace)
                {
                    if (Price == null)
                    {
                        if (replacement == null)
                        {
                            Price = new PropertyState(this);
                        }
                        else
                        {
                            Price = (PropertyState)replacement;
                        }
                    }
                }

                instance = Price;
                break;
            }

            case DataTypeTest.BrowseNames.Dish:
            {
                if (createOrReplace)
                {
                    if (Dish == null)
                    {
                        if (replacement == null)
                        {
                            Dish = new MethodState(this);
                        }
                        else
                        {
                            Dish = (MethodState)replacement;
                        }
                    }
                }

                instance = Dish;
                break;
            }

            case DataTypeTest.BrowseNames.DishId:
            {
                if (createOrReplace)
                {
                    if (DishId == null)
                    {
                        if (replacement == null)
                        {
                            DishId = new PropertyState(this);
                        }
                        else
                        {
                            DishId = (PropertyState)replacement;
                        }
                    }
                }

                instance = DishId;
                break;
            }
            }

            if (instance != null)
            {
                return(instance);
            }

            return(base.FindChild(context, browseName, createOrReplace, replacement));
        }
Ejemplo n.º 23
0
        public MethodState CreateAddMethodState(
            NodeState parent, AasUaBaseEntity.CreateMode mode,
            string browseDisplayName,
            Argument[] inputArgs       = null, Argument[] outputArgs = null, NodeId referenceTypeFromParentId = null,
            NodeId methodDeclarationId = null, GenericMethodCalledEventHandler onCalled = null)
        {
            // method node
            var m = new MethodState(parent);

            m.BrowseName  = "" + browseDisplayName;
            m.DisplayName = "" + browseDisplayName;
            m.Description = new LocalizedText("en", browseDisplayName);
            m.NodeId      = nodeMgr.New(nodeMgr.SystemContext, mode, m);
            if (methodDeclarationId != null)
            {
                m.MethodDeclarationId = methodDeclarationId;
            }

            m.Executable     = true;
            m.UserExecutable = true;

            nodeMgr.AddPredefinedNode(nodeMgr.SystemContext, m);
            if (parent != null)
            {
                parent.AddChild(m);
            }

            if (referenceTypeFromParentId != null)
            {
                if (parent != null)
                {
                    parent.AddReference(referenceTypeFromParentId, false, m.NodeId);
                    if (referenceTypeFromParentId == ReferenceTypeIds.HasComponent)
                    {
                        m.AddReference(referenceTypeFromParentId, true, parent.NodeId);
                    }
                    if (referenceTypeFromParentId == ReferenceTypeIds.HasProperty)
                    {
                        m.AddReference(referenceTypeFromParentId, true, parent.NodeId);
                    }
                }
            }

            // can have inputs, outputs
            for (int i = 0; i < 2; i++)
            {
                // pretty argument list
                var arguments = (i == 0) ? inputArgs : outputArgs;
                if (arguments == null || arguments.Length < 1)
                {
                    continue;
                }

                // make a property for this
                var prop = CreateAddPropertyState <Argument[]>(
                    m, mode,
                    (i == 0) ? "InputArguments" : "OutputArguments",
                    DataTypeIds.Argument,
                    arguments,
                    ReferenceTypeIds.HasProperty,
                    typeDefinitionId: VariableTypeIds.PropertyType,
                    valueRank: 1);

                // explicitely add arguments ass well?
                if (i == 0)
                {
                    m.InputArguments = prop;
                }

                if (i == 1)
                {
                    m.OutputArguments = prop;
                }
            }

            // event handler
            if (onCalled != null)
            {
                m.OnCallMethod = onCalled;
            }


            return(m);
        }
        /// <summary>
        /// Finds the child with the specified browse name.
        /// </summary>
        protected override BaseInstanceState FindChild(
            ISystemContext context,
            QualifiedName browseName,
            bool createOrReplace,
            BaseInstanceState replacement)
        {
            if (QualifiedName.IsNull(browseName))
            {
                return(null);
            }

            BaseInstanceState instance = null;

            switch (browseName.Name)
            {
            case DataTypeTest.BrowseNames.Id:
            {
                if (createOrReplace)
                {
                    if (Id == null)
                    {
                        if (replacement == null)
                        {
                            Id = new BaseDataVariableState(this);
                        }
                        else
                        {
                            Id = (BaseDataVariableState)replacement;
                        }
                    }
                }

                instance = Id;
                break;
            }

            case DataTypeTest.BrowseNames.NameNotSet52:
            {
                if (createOrReplace)
                {
                    if (NameNotSet52 == null)
                    {
                        if (replacement == null)
                        {
                            NameNotSet52 = new BaseDataVariableState <string>(this);
                        }
                        else
                        {
                            NameNotSet52 = (BaseDataVariableState <string>)replacement;
                        }
                    }
                }

                instance = NameNotSet52;
                break;
            }

            case DataTypeTest.BrowseNames.Dishes:
            {
                if (createOrReplace)
                {
                    if (Dishes == null)
                    {
                        if (replacement == null)
                        {
                            Dishes = new BaseObjectState(this);
                        }
                        else
                        {
                            Dishes = (BaseObjectState)replacement;
                        }
                    }
                }

                instance = Dishes;
                break;
            }

            case DataTypeTest.BrowseNames.Menu:
            {
                if (createOrReplace)
                {
                    if (Menu == null)
                    {
                        if (replacement == null)
                        {
                            Menu = new MethodState(this);
                        }
                        else
                        {
                            Menu = (MethodState)replacement;
                        }
                    }
                }

                instance = Menu;
                break;
            }
            }

            if (instance != null)
            {
                return(instance);
            }

            return(base.FindChild(context, browseName, createOrReplace, replacement));
        }
        /// <summary>
        /// Method to start monitoring a node and publish the data to IoTHub. Executes synchronously.
        /// </summary>
        private ServiceResult OnPublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string))
            {
                Trace("PublishNode: Invalid Arguments when trying to publish a node.");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            NodeId         nodeId         = null;
            ExpandedNodeId expandedNodeId = null;
            Uri            endpointUri    = null;
            bool           isNodeIdFormat = true;

            try
            {
                string id = inputArguments[0] as string;
                if (id.Contains("nsu="))
                {
                    expandedNodeId = ExpandedNodeId.Parse(id);
                    isNodeIdFormat = false;
                }
                else
                {
                    nodeId         = NodeId.Parse(id);
                    isNodeIdFormat = true;
                }
                endpointUri = new Uri(inputArguments[1] as string);
            }
            catch (UriFormatException)
            {
                Trace($"PublishNode: The EndpointUri has an invalid format '{inputArguments[1] as string}'!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }
            catch (Exception e)
            {
                Trace(e, $"PublishNode: The NodeId has an invalid format '{inputArguments[0] as string}'!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in NodeId or ExpandedNodeId format as first argument!"));
            }

            // find/create a session to the endpoint URL and start monitoring the node.
            try
            {
                // lock the publishing configuration till we are done
                OpcSessionsListSemaphore.Wait();

                if (ShutdownTokenSource.IsCancellationRequested)
                {
                    return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress."));
                }

                // find the session we need to monitor the node
                OpcSession opcSession = null;
                opcSession = OpcSessions.FirstOrDefault(s => s.EndpointUri.AbsoluteUri.Equals(endpointUri.AbsoluteUri, StringComparison.OrdinalIgnoreCase));

                // add a new session.
                if (opcSession == null)
                {
                    // create new session info.
                    opcSession = new OpcSession(endpointUri, true, OpcSessionCreationTimeout);
                    OpcSessions.Add(opcSession);
                    Trace($"PublishNode: No matching session found for endpoint '{endpointUri.OriginalString}'. Requested to create a new one.");
                }

                if (isNodeIdFormat)
                {
                    // add the node info to the subscription with the default publishing interval, execute syncronously
                    Trace($"PublishNode: Request to monitor item with NodeId '{nodeId.ToString()}' (PublishingInterval: {OpcPublishingInterval}, SamplingInterval: {OpcSamplingInterval})");
                    opcSession.AddNodeForMonitoringAsync(nodeId, null, OpcPublishingInterval, OpcSamplingInterval, ShutdownTokenSource.Token).Wait();
                }
                else
                {
                    // add the node info to the subscription with the default publishing interval, execute syncronously
                    Trace($"PublishNode: Request to monitor item with ExpandedNodeId '{expandedNodeId.ToString()}' (PublishingInterval: {OpcPublishingInterval}, SamplingInterval: {OpcSamplingInterval})");
                    opcSession.AddNodeForMonitoringAsync(null, expandedNodeId, OpcPublishingInterval, OpcSamplingInterval, ShutdownTokenSource.Token).Wait();
                }
            }
            catch (Exception e)
            {
                Trace(e, $"PublishNode: Exception while trying to configure publishing node '{(isNodeIdFormat ? nodeId.ToString() : expandedNodeId.ToString())}'");
                return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}"));
            }
            finally
            {
                OpcSessionsListSemaphore.Release();
            }
            return(ServiceResult.Good);
        }
Ejemplo n.º 26
0
 protected override ServiceResult Call(ISystemContext context, CallMethodRequest methodToCall, MethodState method, CallMethodResult result)
 {
     if (methodToCall.MethodId == new NodeId("Robot1_Stop", NamespaceIndex))
     {
         _mode.Value     = (short)1;
         _mode.Timestamp = DateTime.UtcNow;
         _mode.ClearChangeMasks(SystemContext, false);
         _laser.Value     = false;
         _laser.Timestamp = DateTime.UtcNow;
         _laser.ClearChangeMasks(SystemContext, false);
         result.StatusCode = StatusCodes.Good;
         return(StatusCodes.Good);
     }
     if (methodToCall.MethodId == new NodeId("Robot1_Multiply", NamespaceIndex))
     {
         try
         {
             var a = Convert.ToDouble(methodToCall.InputArguments[0].Value);
             var b = Convert.ToDouble(methodToCall.InputArguments[1].Value);
             result.OutputArguments.Add(new Variant(a * b));
             result.StatusCode = StatusCodes.Good;
             return(StatusCodes.Good);
         }
         catch (Exception e)
         {
             Console.WriteLine(e);
             result.StatusCode = StatusCodes.BadInvalidArgument;
             return(StatusCodes.BadInvalidArgument);
         }
     }
     return(base.Call(context, methodToCall, method, result));
 }
        private ServiceResult UpdateCertificate(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            NodeId certificateGroupId,
            NodeId certificateTypeId,
            byte[] certificate,
            byte[][] issuerCertificates,
            string privateKeyFormat,
            byte[] privateKey,
            ref bool applyChangesRequired)
        {
            HasApplicationSecureAdminAccess(context);

            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            privateKeyFormat = privateKeyFormat?.ToUpper();
            if (!(String.IsNullOrEmpty(privateKeyFormat) || privateKeyFormat == "PEM" || privateKeyFormat == "PFX"))
            {
                throw new ServiceResultException(StatusCodes.BadNotSupported, "The private key format is not supported.");
            }

            ServerCertificateGroup certificateGroup = VerifyGroupAndTypeId(certificateGroupId, certificateTypeId);

            certificateGroup.UpdateCertificate = null;

            X509Certificate2Collection newIssuerCollection = new X509Certificate2Collection();
            X509Certificate2           newCert;

            try
            {
                // build issuer chain
                if (issuerCertificates != null)
                {
                    foreach (byte[] issuerRawCert in issuerCertificates)
                    {
                        var newIssuerCert = new X509Certificate2(issuerRawCert);
                        newIssuerCollection.Add(newIssuerCert);
                    }
                }

                newCert = new X509Certificate2(certificate);
            }
            catch
            {
                throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Certificate data is invalid.");
            }

            // load existing application cert and private key
            if (!Utils.CompareDistinguishedName(certificateGroup.ApplicationCertificate.SubjectName, newCert.SubjectName.Name))
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Subject Name of new certificate doesn't match the application.");
            }

            // self signed
            bool selfSigned = Utils.CompareDistinguishedName(newCert.Subject, newCert.Issuer);

            if (selfSigned && newIssuerCollection.Count != 0)
            {
                throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer list not empty for self signed certificate.");
            }

            if (!selfSigned)
            {
                try
                {
                    // verify cert with issuer chain
                    CertificateValidator            certValidator    = new CertificateValidator();
                    CertificateTrustList            issuerStore      = new CertificateTrustList();
                    CertificateIdentifierCollection issuerCollection = new CertificateIdentifierCollection();
                    foreach (var issuerCert in newIssuerCollection)
                    {
                        issuerCollection.Add(new CertificateIdentifier(issuerCert));
                    }
                    issuerStore.TrustedCertificates = issuerCollection;
                    certValidator.Update(issuerStore, issuerStore, null);
                    certValidator.Validate(newCert);
                }
                catch
                {
                    throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the issuer list.");
                }
            }

            var updateCertificate = new UpdateCertificateData();

            try
            {
                string password = String.Empty;
                switch (privateKeyFormat)
                {
                case null:
                case "":
                {
                    X509Certificate2 certWithPrivateKey = certificateGroup.ApplicationCertificate.LoadPrivateKey(password).Result;
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey);
                    break;
                }

                case "PFX":
                {
                    X509Certificate2 certWithPrivateKey = CertificateFactory.CreateCertificateFromPKCS12(privateKey, password);
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPrivateKey(newCert, certWithPrivateKey);
                    break;
                }

                case "PEM":
                {
                    updateCertificate.CertificateWithPrivateKey = CertificateFactory.CreateCertificateWithPEMPrivateKey(newCert, privateKey, password);
                    break;
                }
                }
                updateCertificate.IssuerCollection = newIssuerCollection;
                updateCertificate.SessionId        = context.SessionId;
            }
            catch
            {
                throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Failed to verify integrity of the new certificate and the private key.");
            }

            certificateGroup.UpdateCertificate = updateCertificate;
            applyChangesRequired = true;

            return(ServiceResult.Good);
        }
Ejemplo n.º 28
0
 public override void Execute(MethodContext context, MethodState state, object localInx = null)
 {
     base.Execute(context, state, 1);
 }
Ejemplo n.º 29
0
        private static void EmitClassMethod(MethodJITInfo method, IntPtr objectptr, IntPtr methodptr, TypeBuilder builder, FieldBuilder addressAssistant)
        {
            MethodState state = new MethodState();

            state.NativeArgs.Add(typeof(IntPtr)); // thisptr

            state.ReturnTypeByStack = method.ReturnType.DetermineProps();

            if (state.ReturnTypeByStack)
            {
                // ref to the native return type
                state.NativeArgs.Add(method.ReturnType.NativeType.MakeByRefType());
                state.NativeReturn = null;
            }
            else if (method.ReturnType.IsStringClass)
            {
                // special case for strings, we will marshal it in ourselves
                state.NativeReturn = typeof(IntPtr);
            }
            else
            {
                state.NativeReturn = method.ReturnType.NativeType;
            }

            state.MethodReturn = method.ReturnType.Type;

            foreach (TypeJITInfo typeInfo in method.Args)
            {
                // populate MethodArgs and NativeArgs now
                typeInfo.DetermineProps();

                state.MethodArgs.Add(typeInfo.Type);

                if (typeInfo.IsStringClass)
                {
                    // we need to specially marshal strings
                    state.NativeArgs.Add(typeof(IntPtr));
                }
                else
                if (!typeInfo.IsParams)
                {
                    if (typeInfo.IsByRef && typeInfo.NativeType.IsValueType)
                    {
                        state.NativeArgs.Add(typeInfo.NativeType.MakeByRefType());
                    }
                    else
                    {
                        state.NativeArgs.Add(typeInfo.NativeType);
                    }
                }
            }

            // add a native version parameter if the return type is detected as a versioned class
            if (method.ReturnType.IsGeneric || (method.ReturnType.IsCreatableClass && method.ReturnType.IsInterfaceVersioned))
            {
                state.NativeArgs.Add(typeof(string));
            }


            MethodBuilder mbuilder = builder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, CallingConventions.HasThis);

            if (method.ReturnType.IsGeneric)
            {
                // create generic param
                GenericTypeParameterBuilder[] gtypeParameters;
                gtypeParameters = mbuilder.DefineGenericParameters(new string[] { "TClass" });

                state.MethodReturn = gtypeParameters[0];
                gtypeParameters[0].SetGenericParameterAttributes(GenericParameterAttributes.ReferenceTypeConstraint);
            }

            mbuilder.SetReturnType(state.MethodReturn);
            mbuilder.SetParameters(state.MethodArgs.ToArray());

            builder.DefineMethodOverride(mbuilder, method.MethodInfo);

            ILGenerator ilgen = mbuilder.GetILGenerator();

            // load object pointer
            EmitPlatformLoad(ilgen, objectptr);

            if (state.ReturnTypeByStack)
            {
                // allocate local to hold the return
                state.localReturn = ilgen.DeclareLocal(method.ReturnType.NativeType);
                state.localReturn.SetLocalSymInfo("nativeReturnPlaceholder");

                ilgen.Emit(OpCodes.Ldloca_S, state.localReturn.LocalIndex);
            }

            int argindex = 0;

            foreach (TypeJITInfo typeInfo in method.Args)
            {
                argindex++;

                // perform any conversions necessary
                if (typeInfo.NativeType != typeInfo.Type && typeInfo.IsByRef)
                {
                    LocalBuilder localArg = ilgen.DeclareLocal(typeInfo.NativeType);
                    localArg.SetLocalSymInfo("byrefarg" + argindex);

                    var helper = new MethodState.RefArgLocal();
                    helper.builder   = localArg;
                    helper.argIndex  = argindex;
                    helper.paramType = typeInfo.PierceType;

                    state.refargLocals.Add(helper);
                    ilgen.Emit(OpCodes.Ldloca_S, localArg);
                }
                else if (typeInfo.NativeType != typeInfo.Type && !typeInfo.Type.IsEnum)
                {
                    EmitPrettyLoad(ilgen, argindex);
                    ilgen.EmitCall(OpCodes.Call, typeInfo.Type.GetMethod("GetValue"), null);
                }
                else
                {
                    EmitPrettyLoad(ilgen, argindex);
                }

                if ((typeInfo.IsStringClass || typeInfo.IsParams) && method.HasParams)
                {
                    if (!typeInfo.IsParams)
                    {
                        continue;
                    }

                    ilgen.EmitCall(OpCodes.Call, typeof(String).GetMethod("Format", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(object[]) }, null), null);
                }

                if (typeInfo.IsStringClass || typeInfo.IsParams)
                {
                    LocalBuilder localString = ilgen.DeclareLocal(typeof(GCHandle));
                    localString.SetLocalSymInfo("nativeString" + argindex);

                    state.unmanagedMemory.Add(localString);

                    // we need to specially marshal strings
                    ilgen.Emit(OpCodes.Ldloca, localString.LocalIndex);
                    ilgen.EmitCall(OpCodes.Call, typeof(InteropHelp).GetMethod("EncodeUTF8String"), null);
                }
                else if (typeInfo.IsCreatableClass)
                {
                    // if this argument is a class we understand: get the object pointer
                    ilgen.Emit(OpCodes.Ldfld, addressAssistant);
                }
            }

            if (method.ReturnType.IsGeneric || (method.ReturnType.IsCreatableClass && method.ReturnType.IsInterfaceVersioned))
            {
                ilgen.Emit(OpCodes.Ldtoken, method.ReturnType.Type);
                ilgen.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Static | BindingFlags.Public), null);
                ilgen.EmitCall(OpCodes.Call, typeof(InterfaceVersions).GetMethod("GetInterfaceIdentifier", BindingFlags.Static | BindingFlags.Public), null);
            }

            // load vtable method pointer
            EmitPlatformLoad(ilgen, methodptr);

            CallingConvention ccv = CallingConvention.ThisCall;

            if (method.HasParams)
            {
                ccv = CallingConvention.Cdecl;
            }

            if (state.NativeReturn == typeof(bool))
            {
                state.NativeReturn = typeof(byte);
            }

            ilgen.EmitCalli(OpCodes.Calli, ccv, state.NativeReturn, state.NativeArgs.ToArray());

            // populate byref args
            foreach (var local in state.refargLocals)
            {
                EmitPrettyLoad(ilgen, local.argIndex);
                EmitPrettyLoadLocal(ilgen, local.builder.LocalIndex);
                ilgen.Emit(OpCodes.Newobj, local.paramType.GetConstructor(new Type[] { local.builder.LocalType }));
                ilgen.Emit(OpCodes.Stind_Ref);
            }

            // clean up unmanaged memory
            foreach (LocalBuilder localbuilder in state.unmanagedMemory)
            {
                ilgen.Emit(OpCodes.Ldloca, localbuilder.LocalIndex);
                ilgen.EmitCall(OpCodes.Call, typeof(InteropHelp).GetMethod("FreeString"), null);
            }

            if (state.ReturnTypeByStack)
            {
                EmitPrettyLoadLocal(ilgen, state.localReturn.LocalIndex);

                // reconstruct return type
                if (state.localReturn.LocalType != state.MethodReturn)
                {
                    ilgen.Emit(OpCodes.Newobj, state.MethodReturn.GetConstructor(new Type[] { state.localReturn.LocalType }));
                }
            }
            else if (method.ReturnType.IsCreatableClass)
            {
                if (method.ReturnType.IsGeneric)
                {
                    ilgen.EmitCall(OpCodes.Call, typeof(JITEngine).GetMethod("GenerateClass", BindingFlags.Static | BindingFlags.Public), null);
                }
                else if (method.ReturnType.IsDelegate)
                {
                    ilgen.Emit(OpCodes.Ldtoken, method.ReturnType.Type);
                    ilgen.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
                    ilgen.EmitCall(OpCodes.Call, typeof(Marshal).GetMethod("GetDelegateForFunctionPointer", BindingFlags.Static | BindingFlags.Public), null);
                    ilgen.Emit(OpCodes.Castclass, method.ReturnType.Type);
                }
                else
                {
                    ilgen.EmitCall(OpCodes.Call, typeof(JITEngine).GetMethod("GenerateClass", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(method.ReturnType.Type), null);
                }
            }
            else if (method.ReturnType.IsStringClass)
            {
                // marshal string return
                ilgen.EmitCall(OpCodes.Call, typeof(InteropHelp).GetMethod("DecodeUTF8String"), null);
            }

            ilgen.Emit(OpCodes.Ret);
        }
Ejemplo n.º 30
0
        private ServiceResult Open(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            OpenFileMode mode,
            TrustListMasks masks,
            ref uint fileHandle)
        {
            HasSecureReadAccess(context);

            if (mode == OpenFileMode.Read)
            {
                HasSecureReadAccess(context);
            }
            else if (mode == (OpenFileMode.Write | OpenFileMode.EraseExisting))
            {
                HasSecureWriteAccess(context);
            }
            else
            {
                return(StatusCodes.BadNotWritable);
            }

            lock (m_lock)
            {
                if (m_sessionId != null)
                {
                    // to avoid deadlocks, last open always wins
                    m_sessionId            = null;
                    m_strm                 = null;
                    m_node.OpenCount.Value = 0;
                }

                m_readMode  = mode == OpenFileMode.Read;
                m_sessionId = context.SessionId;
                fileHandle  = ++m_fileHandle;

                TrustListDataType trustList = new TrustListDataType()
                {
                    SpecifiedLists = (uint)masks
                };

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_trustedStorePath))
                {
                    if ((masks & TrustListMasks.TrustedCertificates) != 0)
                    {
                        X509Certificate2Collection certificates = store.Enumerate().Result;
                        foreach (var certificate in certificates)
                        {
                            trustList.TrustedCertificates.Add(certificate.RawData);
                        }
                    }

                    if ((masks & TrustListMasks.TrustedCrls) != 0)
                    {
                        foreach (var crl in store.EnumerateCRLs())
                        {
                            trustList.TrustedCrls.Add(crl.RawData);
                        }
                    }
                }

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(m_issuerStorePath))
                {
                    if ((masks & TrustListMasks.IssuerCertificates) != 0)
                    {
                        X509Certificate2Collection certificates = store.Enumerate().Result;
                        foreach (var certificate in certificates)
                        {
                            trustList.IssuerCertificates.Add(certificate.RawData);
                        }
                    }

                    if ((masks & TrustListMasks.IssuerCrls) != 0)
                    {
                        foreach (var crl in store.EnumerateCRLs())
                        {
                            trustList.IssuerCrls.Add(crl.RawData);
                        }
                    }
                }

                if (m_readMode)
                {
                    m_strm = EncodeTrustListData(context, trustList);
                }
                else
                {
                    m_strm = new MemoryStream(DefaultTrustListCapacity);
                }

                m_node.OpenCount.Value = 1;
            }

            return(ServiceResult.Good);
        }
Ejemplo n.º 31
0
        private ServiceResult RemoveCertificate(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            string thumbprint,
            bool isTrustedCertificate)
        {
            HasSecureWriteAccess(context);

            lock (m_lock)
            {
                if (m_sessionId != null)
                {
                    return(StatusCodes.BadInvalidState);
                }

                if (String.IsNullOrEmpty(thumbprint))
                {
                    return(StatusCodes.BadInvalidArgument);
                }

                using (ICertificateStore store = CertificateStoreIdentifier.OpenStore(isTrustedCertificate ? m_trustedStorePath : m_issuerStorePath))
                {
                    var certCollection = store.FindByThumbprint(thumbprint).Result;

                    if (certCollection.Count == 0)
                    {
                        return(StatusCodes.BadInvalidArgument);
                    }

                    // delete all CRLs signed by cert
                    var crlsToDelete = new List <X509CRL>();
                    foreach (var crl in store.EnumerateCRLs())
                    {
                        foreach (var cert in certCollection)
                        {
                            if (Utils.CompareDistinguishedName(cert.Subject, crl.Issuer) &&
                                crl.VerifySignature(cert, false))
                            {
                                crlsToDelete.Add(crl);
                                break;
                            }
                        }
                    }

                    if (!store.Delete(thumbprint).Result)
                    {
                        return(StatusCodes.BadInvalidArgument);
                    }

                    foreach (var crl in crlsToDelete)
                    {
                        if (!store.DeleteCRL(crl))
                        {
                            // intentionally ignore errors, try best effort
                            Utils.Trace("RemoveCertificate: Failed to delete CRL {0}.", crl.ToString());
                        }
                    }
                }

                m_node.LastUpdateTime.Value = DateTime.UtcNow;
            }

            return(ServiceResult.Good);
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Imports a node from the set.
        /// </summary>
        private NodeState Import(ISystemContext context, UANode node)
        {
            NodeState importedNode = null;

            NodeClass nodeClass = NodeClass.Unspecified;

            if (node is UAObject)
            {
                nodeClass = NodeClass.Object;
            }
            else if (node is UAVariable)
            {
                nodeClass = NodeClass.Variable;
            }
            else if (node is UAMethod)
            {
                nodeClass = NodeClass.Method;
            }
            else if (node is UAObjectType)
            {
                nodeClass = NodeClass.ObjectType;
            }
            else if (node is UAVariableType)
            {
                nodeClass = NodeClass.VariableType;
            }
            else if (node is UADataType)
            {
                nodeClass = NodeClass.DataType;
            }
            else if (node is UAReferenceType)
            {
                nodeClass = NodeClass.ReferenceType;
            }
            else if (node is UAView)
            {
                nodeClass = NodeClass.View;
            }

            switch (nodeClass)
            {
            case NodeClass.Object:
            {
                UAObject        o     = (UAObject)node;
                BaseObjectState value = new BaseObjectState(null);
                value.EventNotifier = o.EventNotifier;
                importedNode        = value;
                break;
            }

            case NodeClass.Variable:
            {
                UAVariable o = (UAVariable)node;

                NodeId typeDefinitionId = null;

                if (node.References != null)
                {
                    for (int ii = 0; ii < node.References.Length; ii++)
                    {
                        Opc.Ua.NodeId         referenceTypeId = ImportNodeId(node.References[ii].ReferenceType, context.NamespaceUris, true);
                        bool                  isInverse       = !node.References[ii].IsForward;
                        Opc.Ua.ExpandedNodeId targetId        = ImportExpandedNodeId(node.References[ii].Value, context.NamespaceUris, context.ServerUris);

                        if (referenceTypeId == ReferenceTypeIds.HasTypeDefinition && !isInverse)
                        {
                            typeDefinitionId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            break;
                        }
                    }
                }

                BaseVariableState value = null;

                if (typeDefinitionId == Opc.Ua.VariableTypeIds.PropertyType)
                {
                    value = new PropertyState(null);
                }
                else
                {
                    value = new BaseDataVariableState(null);
                }

                value.DataType                = ImportNodeId(o.DataType, context.NamespaceUris, true);
                value.ValueRank               = o.ValueRank;
                value.ArrayDimensions         = ImportArrayDimensions(o.ArrayDimensions);
                value.AccessLevelEx           = o.AccessLevel;
                value.UserAccessLevel         = (byte)(o.AccessLevel & 0xFF);
                value.MinimumSamplingInterval = o.MinimumSamplingInterval;
                value.Historizing             = o.Historizing;

                if (o.Value != null)
                {
                    XmlDecoder decoder  = CreateDecoder(context, o.Value);
                    TypeInfo   typeInfo = null;
                    value.Value = decoder.ReadVariantContents(out typeInfo);
                    decoder.Close();
                }

                importedNode = value;
                break;
            }

            case NodeClass.Method:
            {
                UAMethod    o     = (UAMethod)node;
                MethodState value = new MethodState(null);
                value.Executable       = o.Executable;
                value.UserExecutable   = o.Executable;
                value.TypeDefinitionId = ImportNodeId(o.MethodDeclarationId, context.NamespaceUris, true);
                importedNode           = value;
                break;
            }

            case NodeClass.View:
            {
                UAView    o     = (UAView)node;
                ViewState value = new ViewState();
                value.ContainsNoLoops = o.ContainsNoLoops;
                importedNode          = value;
                break;
            }

            case NodeClass.ObjectType:
            {
                UAObjectType        o     = (UAObjectType)node;
                BaseObjectTypeState value = new BaseObjectTypeState();
                value.IsAbstract = o.IsAbstract;
                importedNode     = value;
                break;
            }

            case NodeClass.VariableType:
            {
                UAVariableType        o     = (UAVariableType)node;
                BaseVariableTypeState value = new BaseDataVariableTypeState();
                value.IsAbstract      = o.IsAbstract;
                value.DataType        = ImportNodeId(o.DataType, context.NamespaceUris, true);
                value.ValueRank       = o.ValueRank;
                value.ArrayDimensions = ImportArrayDimensions(o.ArrayDimensions);

                if (o.Value != null)
                {
                    XmlDecoder decoder  = CreateDecoder(context, o.Value);
                    TypeInfo   typeInfo = null;
                    value.Value = decoder.ReadVariantContents(out typeInfo);
                    decoder.Close();
                }

                importedNode = value;
                break;
            }

            case NodeClass.DataType:
            {
                UADataType    o     = (UADataType)node;
                DataTypeState value = new DataTypeState();
                value.IsAbstract = o.IsAbstract;
                Opc.Ua.DataTypeDefinition dataTypeDefinition = Import(o, o.Definition, context.NamespaceUris);
                value.DataTypeDefinition = new ExtensionObject(dataTypeDefinition);
                value.Purpose            = o.Purpose;
                value.DataTypeModifier   = DataTypeModifier.None;

                if (o.Definition != null)
                {
                    if (o.Definition.IsOptionSet)
                    {
                        value.DataTypeModifier = DataTypeModifier.OptionSet;
                    }
                    else if (o.Definition.IsUnion)
                    {
                        value.DataTypeModifier = DataTypeModifier.Union;
                    }
                }

                importedNode = value;
                break;
            }

            case NodeClass.ReferenceType:
            {
                UAReferenceType    o     = (UAReferenceType)node;
                ReferenceTypeState value = new ReferenceTypeState();
                value.IsAbstract  = o.IsAbstract;
                value.InverseName = Import(o.InverseName);
                value.Symmetric   = o.Symmetric;
                importedNode      = value;
                break;
            }
            }

            importedNode.NodeId      = ImportNodeId(node.NodeId, context.NamespaceUris, false);
            importedNode.BrowseName  = ImportQualifiedName(node.BrowseName, context.NamespaceUris);
            importedNode.DisplayName = Import(node.DisplayName);

            if (importedNode.DisplayName == null)
            {
                importedNode.DisplayName = new Ua.LocalizedText(importedNode.BrowseName.Name);
            }

            importedNode.Description   = Import(node.Description);
            importedNode.Categories    = (node.Category != null && node.Category.Length > 0) ? node.Category : null;
            importedNode.ReleaseStatus = node.ReleaseStatus;
            importedNode.WriteMask     = (AttributeWriteMask)node.WriteMask;
            importedNode.UserWriteMask = (AttributeWriteMask)node.UserWriteMask;

            if (!String.IsNullOrEmpty(node.SymbolicName))
            {
                importedNode.SymbolicName = node.SymbolicName;
            }

            if (node.References != null)
            {
                BaseInstanceState instance = importedNode as BaseInstanceState;
                BaseTypeState     type     = importedNode as BaseTypeState;

                for (int ii = 0; ii < node.References.Length; ii++)
                {
                    Opc.Ua.NodeId         referenceTypeId = ImportNodeId(node.References[ii].ReferenceType, context.NamespaceUris, true);
                    bool                  isInverse       = !node.References[ii].IsForward;
                    Opc.Ua.ExpandedNodeId targetId        = ImportExpandedNodeId(node.References[ii].Value, context.NamespaceUris, context.ServerUris);

                    if (instance != null)
                    {
                        if (referenceTypeId == ReferenceTypeIds.HasModellingRule && !isInverse)
                        {
                            instance.ModellingRuleId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            continue;
                        }

                        if (referenceTypeId == ReferenceTypeIds.HasTypeDefinition && !isInverse)
                        {
                            instance.TypeDefinitionId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            continue;
                        }
                    }

                    if (type != null)
                    {
                        if (referenceTypeId == ReferenceTypeIds.HasSubtype && isInverse)
                        {
                            type.SuperTypeId = Opc.Ua.ExpandedNodeId.ToNodeId(targetId, context.NamespaceUris);
                            continue;
                        }
                    }

                    importedNode.AddReference(referenceTypeId, isInverse, targetId);
                }
            }

            return(importedNode);
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Adds a node to the set.
        /// </summary>
        public void Export(ISystemContext context, NodeState node, bool outputRedundantNames = true)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (Opc.Ua.NodeId.IsNull(node.NodeId))
            {
                throw new ArgumentException("A non-null NodeId must be specified.");
            }

            UANode exportedNode = null;

            switch (node.NodeClass)
            {
            case NodeClass.Object:
            {
                BaseObjectState o     = (BaseObjectState)node;
                UAObject        value = new UAObject();
                value.EventNotifier = o.EventNotifier;

                if (o.Parent != null)
                {
                    value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris);
                }

                exportedNode = value;
                break;
            }

            case NodeClass.Variable:
            {
                BaseVariableState o     = (BaseVariableState)node;
                UAVariable        value = new UAVariable();
                value.DataType                = ExportAlias(o.DataType, context.NamespaceUris);
                value.ValueRank               = o.ValueRank;
                value.ArrayDimensions         = Export(o.ArrayDimensions);
                value.AccessLevel             = o.AccessLevelEx;
                value.MinimumSamplingInterval = o.MinimumSamplingInterval;
                value.Historizing             = o.Historizing;

                if (o.Parent != null)
                {
                    value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris);
                }

                if (o.Value != null)
                {
                    XmlEncoder encoder = CreateEncoder(context);

                    Variant variant = new Variant(o.Value);
                    encoder.WriteVariantContents(variant.Value, variant.TypeInfo);

                    XmlDocument document = new XmlDocument();
                    document.InnerXml = encoder.Close();
                    value.Value       = document.DocumentElement;
                }

                exportedNode = value;
                break;
            }

            case NodeClass.Method:
            {
                MethodState o     = (MethodState)node;
                UAMethod    value = new UAMethod();
                value.Executable = o.Executable;

                if (o.TypeDefinitionId != o.NodeId)
                {
                    value.MethodDeclarationId = Export(o.TypeDefinitionId, context.NamespaceUris);
                }

                if (o.Parent != null)
                {
                    value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris);
                }

                exportedNode = value;
                break;
            }

            case NodeClass.View:
            {
                ViewState o     = (ViewState)node;
                UAView    value = new UAView();
                value.ContainsNoLoops = o.ContainsNoLoops;
                exportedNode          = value;
                break;
            }

            case NodeClass.ObjectType:
            {
                BaseObjectTypeState o     = (BaseObjectTypeState)node;
                UAObjectType        value = new UAObjectType();
                value.IsAbstract = o.IsAbstract;
                exportedNode     = value;
                break;
            }

            case NodeClass.VariableType:
            {
                BaseVariableTypeState o     = (BaseVariableTypeState)node;
                UAVariableType        value = new UAVariableType();
                value.IsAbstract      = o.IsAbstract;
                value.DataType        = ExportAlias(o.DataType, context.NamespaceUris);
                value.ValueRank       = o.ValueRank;
                value.ArrayDimensions = Export(o.ArrayDimensions);

                if (o.Value != null)
                {
                    XmlEncoder encoder = CreateEncoder(context);

                    Variant variant = new Variant(o.Value);
                    encoder.WriteVariantContents(variant.Value, variant.TypeInfo);

                    XmlDocument document = new XmlDocument();
                    document.InnerXml = encoder.Close();
                    value.Value       = document.DocumentElement;
                }

                exportedNode = value;
                break;
            }

            case NodeClass.DataType:
            {
                DataTypeState o     = (DataTypeState)node;
                UADataType    value = new UADataType();
                value.IsAbstract = o.IsAbstract;
                value.Definition = Export(o, o.DataTypeDefinition, context.NamespaceUris, outputRedundantNames);
                value.Purpose    = o.Purpose;
                exportedNode     = value;
                break;
            }

            case NodeClass.ReferenceType:
            {
                ReferenceTypeState o     = (ReferenceTypeState)node;
                UAReferenceType    value = new UAReferenceType();
                value.IsAbstract = o.IsAbstract;

                if (!Opc.Ua.LocalizedText.IsNullOrEmpty(o.InverseName))
                {
                    value.InverseName = Export(new Opc.Ua.LocalizedText[] { o.InverseName });
                }

                value.Symmetric = o.Symmetric;
                exportedNode    = value;
                break;
            }
            }

            exportedNode.NodeId     = Export(node.NodeId, context.NamespaceUris);
            exportedNode.BrowseName = Export(node.BrowseName, context.NamespaceUris);

            if (outputRedundantNames || node.DisplayName.Text != node.BrowseName.Name)
            {
                exportedNode.DisplayName = Export(new Opc.Ua.LocalizedText[] { node.DisplayName });
            }
            else
            {
                exportedNode.DisplayName = null;
            }

            if (node.Description != null && !String.IsNullOrEmpty(node.Description.Text))
            {
                exportedNode.Description = Export(new Opc.Ua.LocalizedText[] { node.Description });
            }
            else
            {
                exportedNode.Description = new LocalizedText[0];
            }

            exportedNode.Category      = (node.Categories != null && node.Categories.Count > 0) ? new List <string>(node.Categories).ToArray() : null;
            exportedNode.ReleaseStatus = node.ReleaseStatus;
            exportedNode.WriteMask     = (uint)node.WriteMask;
            exportedNode.UserWriteMask = (uint)node.UserWriteMask;

            if (!String.IsNullOrEmpty(node.SymbolicName) && node.SymbolicName != node.BrowseName.Name)
            {
                exportedNode.SymbolicName = node.SymbolicName;
            }

            // export references.
            INodeBrowser     browser            = node.CreateBrowser(context, null, null, true, BrowseDirection.Both, null, null, true);
            List <Reference> exportedReferences = new List <Reference>();
            IReference       reference          = browser.Next();

            while (reference != null)
            {
                if (node.NodeClass == NodeClass.Method)
                {
                    if (!reference.IsInverse && reference.ReferenceTypeId == ReferenceTypeIds.HasTypeDefinition)
                    {
                        reference = browser.Next();
                        continue;
                    }
                }

                Reference exportedReference = new Reference();

                exportedReference.ReferenceType = ExportAlias(reference.ReferenceTypeId, context.NamespaceUris);
                exportedReference.IsForward     = !reference.IsInverse;
                exportedReference.Value         = Export(reference.TargetId, context.NamespaceUris, context.ServerUris);
                exportedReferences.Add(exportedReference);

                reference = browser.Next();
            }

            exportedNode.References = exportedReferences.ToArray();

            // add node to list.
            UANode[] nodes = null;

            int count = 1;

            if (this.Items == null)
            {
                nodes = new UANode[count];
            }
            else
            {
                count += this.Items.Length;
                nodes  = new UANode[count];
                Array.Copy(this.Items, nodes, this.Items.Length);
            }

            nodes[count - 1] = exportedNode;

            this.Items = nodes;

            // recusively process children.
            List <BaseInstanceState> children = new List <BaseInstanceState>();

            node.GetChildren(context, children);

            for (int ii = 0; ii < children.Count; ii++)
            {
                Export(context, children[ii], outputRedundantNames);
            }
        }
        /// <summary>
        /// Method to start monitoring a node and publish the data to IoTHub. Executes synchronously.
        /// </summary>
        private ServiceResult OnPublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            string logPrefix = "OnPublishNodeCall:";

            if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string))
            {
                Logger.Error($"{logPrefix} Invalid Arguments when trying to publish a node.");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            HttpStatusCode statusCode     = HttpStatusCode.InternalServerError;
            NodeId         nodeId         = null;
            ExpandedNodeId expandedNodeId = null;
            Uri            endpointUri    = null;
            bool           isNodeIdFormat = true;

            try
            {
                string id = inputArguments[0] as string;
                if (id.Contains("nsu=", StringComparison.InvariantCulture))
                {
                    expandedNodeId = ExpandedNodeId.Parse(id);
                    isNodeIdFormat = false;
                }
                else
                {
                    nodeId         = NodeId.Parse(id);
                    isNodeIdFormat = true;
                }
                endpointUri = new Uri(inputArguments[1] as string);
            }
            catch (UriFormatException)
            {
                Logger.Error($"{logPrefix} The EndpointUrl has an invalid format '{inputArguments[1] as string}'!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }
            catch (Exception e)
            {
                Logger.Error(e, $"{logPrefix} The NodeId has an invalid format '{inputArguments[0] as string}'!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in NodeId or ExpandedNodeId format as first argument!"));
            }

            // find/create a session to the endpoint URL and start monitoring the node.
            try
            {
                // lock the publishing configuration till we are done
                NodeConfiguration.OpcSessionsListSemaphore.Wait();

                if (ShutdownTokenSource.IsCancellationRequested)
                {
                    return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress."));
                }

                // find the session we need to monitor the node
                IOpcSession opcSession = null;
                opcSession = NodeConfiguration.OpcSessions.FirstOrDefault(s => s.EndpointUrl.Equals(endpointUri.OriginalString, StringComparison.OrdinalIgnoreCase));

                // add a new session.
                if (opcSession == null)
                {
                    // create new session info.
                    // endpointName is null here. Since we currently do not have to support configuration of OPC Publisher by OPC server this is ok for now.
                    opcSession = new OpcSession(Guid.NewGuid(), null, endpointUri.OriginalString, true, OpcSessionCreationTimeout, OpcAuthenticationMode.Anonymous, null);
                    NodeConfiguration.OpcSessions.Add(opcSession);
                    Logger.Information($"OnPublishNodeCall: No matching session found for endpoint '{endpointUri.OriginalString}'. Requested to create a new one.");
                }

                // Add a node. The key for the new node is the node id / expanded node id
                if (isNodeIdFormat)
                {
                    // add the node info to the subscription with the default publishing interval, execute syncronously
                    Logger.Debug($"{logPrefix} Request to monitor item with NodeId '{nodeId.ToString()}' (with default PublishingInterval and SamplingInterval)");
                    statusCode = opcSession.AddNodeForMonitoringAsync(nodeId, null, null, null, nodeId.ToString(), null, null, null, ShutdownTokenSource.Token, null).Result;
                }
                else
                {
                    // add the node info to the subscription with the default publishing interval, execute syncronously
                    Logger.Debug($"{logPrefix} Request to monitor item with ExpandedNodeId '{expandedNodeId.ToString()}' (with default PublishingInterval and SamplingInterval)");
                    statusCode = opcSession.AddNodeForMonitoringAsync(null, expandedNodeId, null, null, expandedNodeId.ToString(), null, null, null, ShutdownTokenSource.Token, null).Result;
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, $"{logPrefix} Exception while trying to configure publishing node '{(isNodeIdFormat ? nodeId.ToString() : expandedNodeId.ToString())}'");
                return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error publishing node: {e.Message}"));
            }
            finally
            {
                NodeConfiguration.OpcSessionsListSemaphore.Release();
            }

            if (statusCode == HttpStatusCode.OK || statusCode == HttpStatusCode.Accepted)
            {
                return(ServiceResult.Good);
            }
            return(ServiceResult.Create(StatusCodes.Bad, "Can not start monitoring node! Reason unknown."));
        }
Ejemplo n.º 35
0
 public void Execute(MethodState state, Instruction inst)
 {
     state.InstructionPointer = MethodState.RETURN_INSTRUCTION_POINTER;
 }
Ejemplo n.º 36
0
        /// <summary>
        /// Method exposed as a node in the server to un-publish a node from IoT Hub that it is connected to
        /// </summary>
        private ServiceResult UnPublishNodeMethod(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (inputArguments[0] == null || inputArguments[1] == null)
            {
                Program.Trace("UnPublishNodeMethod: Invalid arguments!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!"));
            }

            string nodeID = inputArguments[0] as string;
            string uri    = inputArguments[1] as string;

            if (string.IsNullOrEmpty(nodeID) || string.IsNullOrEmpty(uri))
            {
                Program.Trace("UnPublishNodeMethod: Arguments are not valid strings!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            NodeLookup lookup = new NodeLookup();

            lookup.NodeID = new NodeId(nodeID);
            try
            {
                lookup.EndPointURL = new Uri(uri);
            }
            catch (UriFormatException)
            {
                Program.Trace("UnPublishNodeMethod: Invalid endpoint URL!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }

            // find the right session using our lookup
            Session matchingSession = null;

            foreach (Session session in Program.m_sessions)
            {
                char[] trimChars = { '/', ' ' };
                if (session.Endpoint.EndpointUrl.TrimEnd(trimChars).Equals(lookup.EndPointURL.ToString().TrimEnd(trimChars), StringComparison.OrdinalIgnoreCase))
                {
                    matchingSession = session;
                    break;
                }
            }

            if (matchingSession == null)
            {
                Program.Trace("UnPublishNodeMethod: Session for published node not found: " + lookup.EndPointURL.ToString());
                return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for published node not found!"));
            }

            // find the right monitored item to remove
            foreach (MonitoredItem item in matchingSession.DefaultSubscription.MonitoredItems)
            {
                if (item.StartNodeId == lookup.NodeID)
                {
                    matchingSession.DefaultSubscription.RemoveItem(item);
                    Program.Trace("UnPublishNodeMethod: Successful unpublish: " + lookup.NodeID.ToString());

                    // update our data on success only
                    // we keep the session to the server, as there may be other nodes still published on it
                    var itemToRemove = Program.m_nodesLookups.Find(l => l.NodeID == lookup.NodeID && l.EndPointURL == lookup.EndPointURL);
                    Program.m_nodesLookups.Remove(itemToRemove);

                    //serialize Program.m_nodesLookups to disk
                    string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
                    if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
                    {
                        publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP");
                    }
                    File.WriteAllText(publishedNodesFilePath, JsonConvert.SerializeObject(Program.m_nodesLookups));

                    return(ServiceResult.Good);
                }
            }

            Program.Trace("UnPublishNodeMethod: Monitored item for node ID not found " + lookup.NodeID.ToString());
            return(ServiceResult.Create(StatusCodes.BadNodeIdInvalid, "Monitored item for node ID not found!"));
        }
Ejemplo n.º 37
0
 public override void Execute(MethodContext context, MethodState state, object operand = null)
 {
     base.Execute(context, state, operand);
 }
Ejemplo n.º 38
0
        /// <summary>
        /// Does any initialization required before the address space can be used.
        /// </summary>
        /// <remarks>
        /// The externalReferences is an out parameter that allows the node manager to link to nodes
        /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
        /// should have a reference to the root folder node(s) exposed by this node manager.
        /// </remarks>
        public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences)
        {
            lock (Lock)
            {
                // create a object to represent the process being controlled.
                BaseObjectState process = new BaseObjectState(null);

                process.NodeId           = new NodeId(1, NamespaceIndex);
                process.BrowseName       = new QualifiedName("My Process", NamespaceIndex);
                process.DisplayName      = process.BrowseName.Name;
                process.TypeDefinitionId = ObjectTypeIds.BaseObjectType;

                // ensure the process object can be found via the server object.
                IList <IReference> references = null;

                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>();
                }

                process.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder);
                references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, process.NodeId));

                // a property to report the process state.
                PropertyState <uint> state = m_stateNode = new PropertyState <uint>(process);

                state.NodeId           = new NodeId(2, NamespaceIndex);
                state.BrowseName       = new QualifiedName("State", NamespaceIndex);
                state.DisplayName      = state.BrowseName.Name;
                state.TypeDefinitionId = VariableTypeIds.PropertyType;
                state.ReferenceTypeId  = ReferenceTypeIds.HasProperty;
                state.DataType         = DataTypeIds.UInt32;
                state.ValueRank        = ValueRanks.Scalar;

                process.AddChild(state);

                // a method to start the process.
                MethodState start = new MethodState(process);

                start.NodeId          = new NodeId(3, NamespaceIndex);
                start.BrowseName      = new QualifiedName("Start", NamespaceIndex);
                start.DisplayName     = start.BrowseName.Name;
                start.ReferenceTypeId = ReferenceTypeIds.HasComponent;
                start.UserExecutable  = true;
                start.Executable      = true;

                // add input arguments.
                start.InputArguments                  = new PropertyState <Argument[]>(start);
                start.InputArguments.NodeId           = new NodeId(4, NamespaceIndex);
                start.InputArguments.BrowseName       = BrowseNames.InputArguments;
                start.InputArguments.DisplayName      = start.InputArguments.BrowseName.Name;
                start.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType;
                start.InputArguments.ReferenceTypeId  = ReferenceTypeIds.HasProperty;
                start.InputArguments.DataType         = DataTypeIds.Argument;
                start.InputArguments.ValueRank        = ValueRanks.OneDimension;

                Argument[] args = new Argument[2];
                args[0]             = new Argument();
                args[0].Name        = "Initial State";
                args[0].Description = "The initialize state for the process.";
                args[0].DataType    = DataTypeIds.UInt32;
                args[0].ValueRank   = ValueRanks.Scalar;

                args[1]             = new Argument();
                args[1].Name        = "Final State";
                args[1].Description = "The final state for the process.";
                args[1].DataType    = DataTypeIds.UInt32;
                args[1].ValueRank   = ValueRanks.Scalar;

                start.InputArguments.Value = args;

                // add output arguments.
                start.OutputArguments                  = new PropertyState <Argument[]>(start);
                start.OutputArguments.NodeId           = new NodeId(5, NamespaceIndex);
                start.OutputArguments.BrowseName       = BrowseNames.OutputArguments;
                start.OutputArguments.DisplayName      = start.OutputArguments.BrowseName.Name;
                start.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType;
                start.OutputArguments.ReferenceTypeId  = ReferenceTypeIds.HasProperty;
                start.OutputArguments.DataType         = DataTypeIds.Argument;
                start.OutputArguments.ValueRank        = ValueRanks.OneDimension;

                args                = new Argument[2];
                args[0]             = new Argument();
                args[0].Name        = "Revised Initial State";
                args[0].Description = "The revised initialize state for the process.";
                args[0].DataType    = DataTypeIds.UInt32;
                args[0].ValueRank   = ValueRanks.Scalar;

                args[1]             = new Argument();
                args[1].Name        = "Revised Final State";
                args[1].Description = "The revised final state for the process.";
                args[1].DataType    = DataTypeIds.UInt32;
                args[1].ValueRank   = ValueRanks.Scalar;

                start.OutputArguments.Value = args;

                process.AddChild(start);

                // save in dictionary.
                AddPredefinedNode(SystemContext, process);

                // set up method handlers.
                start.OnCallMethod = new GenericMethodCalledEventHandler(OnStart);
            }
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Calls a method on the specified nodes.
        /// </summary>
        public override void Call(
            OperationContext context,
            IList <CallMethodRequest> methodsToCall,
            IList <CallMethodResult> results,
            IList <ServiceResult> errors)
        {
            ServerSystemContext             systemContext  = SystemContext.Copy(context);
            IDictionary <NodeId, NodeState> operationCache = new NodeIdDictionary <NodeState>();

            bool didRefresh = false;

            for (int ii = 0; ii < methodsToCall.Count; ii++)
            {
                CallMethodRequest methodToCall = methodsToCall[ii];

                bool refreshMethod = methodToCall.MethodId.Equals(Opc.Ua.MethodIds.ConditionType_ConditionRefresh) ||
                                     methodToCall.MethodId.Equals(Opc.Ua.MethodIds.ConditionType_ConditionRefresh2);

                if (refreshMethod)
                {
                    if (didRefresh)
                    {
                        errors[ii]             = StatusCodes.BadRefreshInProgress;
                        methodToCall.Processed = true;
                        continue;
                    }
                    else
                    {
                        didRefresh = true;
                    }
                }

                bool ackMethod        = methodToCall.MethodId.Equals(Opc.Ua.MethodIds.AcknowledgeableConditionType_Acknowledge);
                bool confirmMethod    = methodToCall.MethodId.Equals(Opc.Ua.MethodIds.AcknowledgeableConditionType_Confirm);
                bool commentMethod    = methodToCall.MethodId.Equals(Opc.Ua.MethodIds.ConditionType_AddComment);
                bool ackConfirmMethod = ackMethod || confirmMethod || commentMethod;

                // Need to try to capture any calls to ConditionType::Acknowledge
                if (methodToCall.ObjectId.Equals(Opc.Ua.ObjectTypeIds.ConditionType) && (ackConfirmMethod))
                {
                    // Mantis Issue 6944 which is a duplicate of 5544 - result is Confirm should be Bad_NodeIdInvalid
                    // Override any other errors that may be there, even if this is 'Processed'
                    errors[ii]             = StatusCodes.BadNodeIdInvalid;
                    methodToCall.Processed = true;
                    continue;
                }

                // skip items that have already been processed.
                if (methodToCall.Processed)
                {
                    continue;
                }

                MethodState method = null;

                lock (Lock)
                {
                    // check for valid handle.
                    NodeHandle initialHandle = GetManagerHandle(systemContext, methodToCall.ObjectId, operationCache);

                    if (initialHandle == null)
                    {
                        if (ackConfirmMethod)
                        {
                            // Mantis 6944
                            errors[ii]             = StatusCodes.BadNodeIdUnknown;
                            methodToCall.Processed = true;
                        }

                        continue;
                    }

                    // owned by this node manager.
                    methodToCall.Processed = true;

                    // Look for an alarm branchId to operate on.
                    NodeHandle handle = FindBranchNodeHandle(systemContext, initialHandle, methodToCall);

                    // validate the source node.
                    NodeState source = ValidateNode(systemContext, handle, operationCache);

                    if (source == null)
                    {
                        errors[ii] = StatusCodes.BadNodeIdUnknown;
                        continue;
                    }

                    // find the method.
                    method = source.FindMethod(systemContext, methodToCall.MethodId);

                    if (method == null)
                    {
                        // check for loose coupling.
                        if (source.ReferenceExists(ReferenceTypeIds.HasComponent, false, methodToCall.MethodId))
                        {
                            method = (MethodState)FindPredefinedNode(methodToCall.MethodId, typeof(MethodState));
                        }

                        if (method == null)
                        {
                            errors[ii] = StatusCodes.BadMethodInvalid;
                            continue;
                        }
                    }
                }

                // call the method.
                CallMethodResult result = results[ii] = new CallMethodResult();

                errors[ii] = Call(
                    systemContext,
                    methodToCall,
                    method,
                    result);
            }
        }
Ejemplo n.º 40
0
        protected override NodeState AddBehaviourToPredefinedNode(ISystemContext context, NodeState predefinedNode)
        {
            // add behaviour to our methods
            MethodState methodState = predefinedNode as MethodState;

            if (methodState != null)
            {
                if (methodState.DisplayName == "Execute")
                {
                    methodState.OnCallMethod = new GenericMethodCalledEventHandler(Execute);

                    // define the method's input argument (the serial number)
                    methodState.InputArguments = new PropertyState <Argument[]>(methodState)
                    {
                        NodeId     = new NodeId(methodState.BrowseName.Name + "InArgs", NamespaceIndex),
                        BrowseName = BrowseNames.InputArguments
                    };
                    methodState.InputArguments.DisplayName      = methodState.InputArguments.BrowseName.Name;
                    methodState.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType;
                    methodState.InputArguments.ReferenceTypeId  = ReferenceTypeIds.HasProperty;
                    methodState.InputArguments.DataType         = DataTypeIds.Argument;
                    methodState.InputArguments.ValueRank        = ValueRanks.OneDimension;

                    methodState.InputArguments.Value = new Argument[]
                    {
                        new Argument {
                            Name = "SerialNumber", Description = "Serial number of the product to make.", DataType = DataTypeIds.UInt64, ValueRank = ValueRanks.Scalar
                        }
                    };

                    return(predefinedNode);
                }
                if (methodState.DisplayName == "Reset")
                {
                    methodState.OnCallMethod = new GenericMethodCalledEventHandler(Reset);
                    return(predefinedNode);
                }
                if (methodState.DisplayName == "OpenPressureReleaseValve")
                {
                    methodState.OnCallMethod = new GenericMethodCalledEventHandler(OpenPressureReleaseValve);
                    return(predefinedNode);
                }
            }

            // also capture the nodeIDs of our instance variables (i.e. NOT the model!)
            BaseDataVariableState variableState = predefinedNode as BaseDataVariableState;

            if ((variableState != null) && (variableState.ModellingRuleId == null))
            {
                if (variableState.DisplayName == "NumberOfManufacturedProducts")
                {
                    m_NumberOfManufacturedProductsID = variableState.NodeId;
                }
                if (variableState.DisplayName == "NumberOfDiscardedProducts")
                {
                    m_NumberOfDiscardedProductsID = variableState.NodeId;
                }
                if (variableState.DisplayName == "ProductSerialNumber")
                {
                    m_ProductSerialNumberID = variableState.NodeId;
                }
                if (variableState.DisplayName == "ActualCycleTime")
                {
                    m_ActualCycleTimeID = variableState.NodeId;
                }
                if (variableState.DisplayName == "EnergyConsumption")
                {
                    m_EnergyConsumptionID = variableState.NodeId;
                }
                if (variableState.DisplayName == "FaultyTime")
                {
                    m_FaultyTimeID = variableState.NodeId;
                }
                if (variableState.DisplayName == "IdealCycleTime")
                {
                    m_IdealCycleTimeID = variableState.NodeId;
                }
                if (variableState.DisplayName == "OverallRunningTime")
                {
                    m_OverallRunningTimeID = variableState.NodeId;
                }
                if (variableState.DisplayName == "Pressure")
                {
                    m_PressureID = variableState.NodeId;
                }
                if (variableState.DisplayName == "Status")
                {
                    m_StatusID = variableState.NodeId;
                }
            }

            return(predefinedNode);
        }
Ejemplo n.º 41
0
        /// <summary>
        /// Called when a client locks the server.
        /// </summary>
        public ServiceResult OnUnlockServer(
            ISystemContext context,
            MethodState method,
            IList<object> inputArguments,
            IList<object> outputArguments)
        {
            ServerSystemContext systemContext = context as ServerSystemContext;

            if (m_serverLockHolder != null)
            {
                if (m_serverLockHolder != systemContext.SessionId)
                {
                    return StatusCodes.BadSessionIdInvalid;
                }
            }

            m_serverLockHolder = null;

            return ServiceResult.Good;
        }
Ejemplo n.º 42
0
        private ServiceResult Reset(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            m_status = StationStatus.Ready;

            return(ServiceResult.Good);
        }
        /// <summary>
        /// Calls a method on an object.
        /// </summary>
        protected virtual ServiceResult Call(
            ISystemContext context,
            CallMethodRequest methodToCall,
            NodeState source,
            MethodState method,
            CallMethodResult result)
        {
            ServerSystemContext systemContext = context as ServerSystemContext;
            List<ServiceResult> argumentErrors = new List<ServiceResult>();
            VariantCollection outputArguments = new VariantCollection();

            ServiceResult error = method.Call(
                context,
                source.NodeId,
                methodToCall.InputArguments,
                argumentErrors,
                outputArguments);

            if (ServiceResult.IsBad(error))
            {
                return error;
            }

            // check for argument errors.
            bool argumentsValid = true;

            for (int jj = 0; jj < argumentErrors.Count; jj++)
            {
                ServiceResult argumentError = argumentErrors[jj];

                if (argumentError != null)
                {
                    result.InputArgumentResults.Add(argumentError.StatusCode);
                                  
                    if (ServiceResult.IsBad(argumentError))
                    {
                        argumentsValid = false;
                    }
                }
                else
                {
                    result.InputArgumentResults.Add(StatusCodes.Good);
                }

                // only fill in diagnostic info if it is requested.
                if ((systemContext.OperationContext.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                {
                    if (ServiceResult.IsBad(argumentError))
                    {
                        argumentsValid = false;
                        result.InputArgumentDiagnosticInfos.Add(new DiagnosticInfo(argumentError, systemContext.OperationContext.DiagnosticsMask, false, systemContext.OperationContext.StringTable));
                    }
                    else
                    {
                        result.InputArgumentDiagnosticInfos.Add(null);
                    }
                }
            }

            // check for validation errors.
            if (!argumentsValid)
            {
                result.StatusCode = StatusCodes.BadInvalidArgument;
                return result.StatusCode;
            }

            // do not return diagnostics if there are no errors.
            result.InputArgumentDiagnosticInfos.Clear();

            // return output arguments.
            result.OutputArguments = outputArguments;

            return ServiceResult.Good;
        }
Ejemplo n.º 44
0
        private ServiceResult OpenPressureReleaseValve(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            m_pressure = 1000;

            return(ServiceResult.Good);
        }