Esempio n. 1
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));
 }
Esempio n. 2
0
        /// <summary>
        /// Handles the Click event of the Conditions_RefreshMI control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Conditions_RefreshMI_Click(object sender, EventArgs e)
        {
            try
            {
                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = ObjectTypeIds.ConditionType;
                request.MethodId = MethodIds.ConditionType_ConditionRefresh;
                request.InputArguments.Add(new Variant(m_subscription.Id));

                CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();
                methodsToCall.Add(request);

                CallMethodResultCollection results         = null;
                DiagnosticInfoCollection   diagnosticInfos = null;

                m_session.Call(
                    null,
                    methodsToCall,
                    out results,
                    out diagnosticInfos);

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

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw ServiceResultException.Create((uint)results[0].StatusCode, "Unexpected error calling RefreshConditions.");
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
        private bool PublishOneNode(NodeIdInfo nodeIdInfo)
        {
            string logPrefix = $"{_logClassPrefix}:PublishOneNode:";

            try
            {
                int retryCount = 0;
                int maxRetries = 3;
                while (retryCount < maxRetries)
                {
                    VariantCollection inputArguments = new VariantCollection()
                    {
                        nodeIdInfo.Id,
                        TestserverUrl
                    };
                    CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                    CallMethodResultCollection  results         = null;
                    DiagnosticInfoCollection    diagnosticInfos = null;
                    CallMethodRequest           request         = new CallMethodRequest();
                    request.ObjectId       = new NodeId("Methods", 2);
                    request.MethodId       = new NodeId("PublishNode", 2);
                    request.InputArguments = inputArguments;
                    requests.Add(request);
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);

                    if (results[0].StatusCode == StatusCodes.BadSessionNotActivated)
                    {
                        retryCount++;
                        Logger.Warning($"{logPrefix} need to retry to publish node, since session is not yet activated (nodeId: '{nodeIdInfo.Id}', retry: '{retryCount}')");
                        Task.Delay(MaxShortWaitSec * 1000).Wait();
                        continue;
                    }
                    if (!nodeIdInfo.Published && StatusCode.IsBad(results[0].StatusCode))
                    {
                        Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')");
                        return(false);
                    }
                    else
                    {
                        nodeIdInfo.Published = true;
                        Logger.Verbose($"{logPrefix} succeeded (nodeId: '{nodeIdInfo.Id}', error: '{results[0].StatusCode}'");
                        return(true);
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')");
            return(false);
        }
        protected override PublishedNodesCollection GetPublishedNodesLegacy(string endpointUrl, CancellationToken ct)
        {
            string logPrefix = $"{_logClassPrefix}:GetPublishedNodesLegacy:";
            PublishedNodesCollection nodeList = null;

            VariantCollection inputArgumentsTestserver = new VariantCollection()
            {
                ""
            };

            try
            {
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = new CallMethodResultCollection();
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest
                {
                    ObjectId = new NodeId("Methods", 2),
                    MethodId = new NodeId("GetPublishedNodes", 2),
                };
                request.InputArguments = inputArgumentsTestserver;
                requests.Add(request);
                try
                {
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, $"{logPrefix} Exception");
                }
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'");
                }
                else
                {
                    if (results?[0]?.OutputArguments.Count == 1)
                    {
                        string stringResult   = results[0].OutputArguments[0].ToString();
                        int    jsonStartIndex = stringResult.IndexOf("[", StringComparison.InvariantCulture);
                        int    jsonEndIndex   = stringResult.LastIndexOf("]", StringComparison.InvariantCulture);
                        nodeList = JsonConvert.DeserializeObject <PublishedNodesCollection>(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1));
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            return(nodeList);
        }
Esempio n. 5
0
        /// <summary>
        /// Responds to the dialog.
        /// </summary>
        private void Respond(int selectedResponse)
        {
            // build list of dialogs to respond to (caller should always make sure that only one is selected).
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++)
            {
                DialogConditionState dialog = ConditionsLV.SelectedItems[ii].Tag as DialogConditionState;

                if (dialog == null)
                {
                    continue;
                }

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = dialog.NodeId;
                request.MethodId = MethodIds.DialogConditionType_Respond;
                request.InputArguments.Add(new Variant(selectedResponse));
                request.Handle = ConditionsLV.SelectedItems[ii];

                methodsToCall.Add(request);
            }

            if (methodsToCall.Count == 0)
            {
                return;
            }

            // call the methods.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

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

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ListViewItem item = (ListViewItem)methodsToCall[ii].Handle;
                    item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Adds a comment to the selected conditions.
        /// </summary>
        /// <param name="methodId">The NodeId for the method to call.</param>
        /// <param name="comment">The comment to pass as an argument.</param>
        private void CallMethod(NodeId methodId, string comment)
        {
            // build list of methods to call.
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++)
            {
                ConditionState condition = (ConditionState)ConditionsLV.SelectedItems[ii].Tag;

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = condition.NodeId;
                request.MethodId = methodId;
                request.Handle   = ConditionsLV.SelectedItems[ii];

                if (comment != null)
                {
                    request.InputArguments.Add(new Variant(condition.EventId.Value));
                    request.InputArguments.Add(new Variant((LocalizedText)comment));
                }

                methodsToCall.Add(request);
            }

            if (methodsToCall.Count == 0)
            {
                return;
            }

            // call the methods.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

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

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ListViewItem item = (ListViewItem)methodsToCall[ii].Handle;
                    item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode);
                }
            }
        }
Esempio n. 7
0
        private byte[] GetEventIdFromAckConfirmMethod(CallMethodRequest request)
        {
            byte[] eventId = null;

            // Bad magic Numbers here
            if (request.InputArguments != null && request.InputArguments.Count == 2)
            {
                if (request.InputArguments[0].TypeInfo.BuiltInType.Equals(BuiltInType.ByteString))
                {
                    eventId = (byte[])request.InputArguments[0].Value;
                }
            }
            return(eventId);
        }
Esempio n. 8
0
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                VariantCollection inputArguments = InputArgumentsCTRL.GetValues();

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId       = m_objectId;
                request.MethodId       = m_methodId;
                request.InputArguments = inputArguments;

                CallMethodRequestCollection requests = new CallMethodRequestCollection();
                requests.Add(request);

                CallMethodResultCollection results;
                DiagnosticInfoCollection   diagnosticInfos;

                ResponseHeader responseHeader = m_session.Call(
                    null,
                    requests,
                    out results,
                    out diagnosticInfos);

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable));
                }

                OutputArgumentsCTRL.SetValues(results[0].OutputArguments);

                if (results[0].OutputArguments.Count == 0)
                {
                    MessageBox.Show(this, "Method executed successfully.");
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        protected override void CallUnknownMethod(CancellationToken ct)
        {
            string logPrefix = $"{_logClassPrefix}:CallUnknownMethod:";

            VariantCollection inputArgumentsMethodCall = new VariantCollection()
            {
                "UnknownMethod",
            };

            try
            {
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = new CallMethodResultCollection();
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest
                {
                    ObjectId = new NodeId("Methods", 2),
                    MethodId = new NodeId("IoTHubDirectMethod", 2),
                };
                request.InputArguments = inputArgumentsMethodCall;
                requests.Add(request);
                try
                {
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, $"{logPrefix} Exception");
                }
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'");
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
        }
        private bool UnpublishOneNode(NodeIdInfo nodeIdInfo, string endpointUrl = null)
        {
            string logPrefix = $"{_logClassPrefix}:UnpublishOneNode:";

            try
            {
                VariantCollection inputArguments = new VariantCollection()
                {
                    nodeIdInfo.Id,
                    endpointUrl ?? TestserverUrl
                };
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = null;
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest();
                request.ObjectId       = new NodeId("Methods", 2);
                request.MethodId       = new NodeId("UnpublishNode", 2);
                request.InputArguments = inputArguments;
                requests.Add(request);
                ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                if (nodeIdInfo.Published && StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')");
                    return(false);
                }
                else
                {
                    nodeIdInfo.Published = false;
                    Logger.Verbose($"{logPrefix} succeeded (nodeId: '{nodeIdInfo.Id}', error: '{results[0].StatusCode}'");
                    return(true);
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            return(false);
        }
Esempio n. 11
0
        /// <summary>
        /// Adds random parameters
        /// </summary>
        private void AddMethodCall(
            TestMethod method,
            CallMethodRequestCollection methodsToCall,
            bool testErrors)
        {
            VariantCollection inputArguments = new VariantCollection();

            for (int ii = 0; ii < method.InputArguments.Count; ii++)
            {
                Argument argument = method.InputArguments[ii];

                object value = m_generator.GetRandom(
                    argument.DataType,
                    argument.ValueRank,
                    argument.ArrayDimensions,
                    Session.TypeTree);

                inputArguments.Add(new Variant(value));
            }

            CallMethodRequest request = null;

            // add valid method.
            if (!testErrors)
            {
                request = new CallMethodRequest();

                request.ObjectId       = method.Parent.NodeId;
                request.MethodId       = method.Method.NodeId;
                request.Handle         = method;
                request.InputArguments = new VariantCollection(inputArguments);

                methodsToCall.Add(request);

                return;
            }

            // add invalid object.
            request = new CallMethodRequest();

            request.ObjectId       = Objects.RootFolder;
            request.MethodId       = method.Method.NodeId;
            request.Handle         = method;
            request.InputArguments = new VariantCollection(inputArguments);

            methodsToCall.Add(request);

            if (inputArguments.Count > 0)
            {
                // add too few parameters.
                request = new CallMethodRequest();

                request.ObjectId       = method.Parent.NodeId;
                request.MethodId       = method.Method.NodeId;
                request.Handle         = method;
                request.InputArguments = new VariantCollection(inputArguments);
                request.InputArguments.RemoveAt(request.InputArguments.Count - 1);

                methodsToCall.Add(request);

                // add invalid parameter.
                request = new CallMethodRequest();

                request.ObjectId       = method.Parent.NodeId;
                request.MethodId       = method.Method.NodeId;
                request.Handle         = method;
                request.InputArguments = new VariantCollection(inputArguments);

                Argument argument = method.InputArguments[inputArguments.Count / 2];

                if (TypeInfo.GetBuiltInType(argument.DataType, Session.TypeTree) != BuiltInType.Variant)
                {
                    TypeInfo typeInfo = null;

                    do
                    {
                        Variant arg = (Variant)m_generator.GetRandom(BuiltInType.Variant);

                        typeInfo = TypeInfo.IsInstanceOfDataType(
                            arg.Value,
                            argument.DataType,
                            argument.ValueRank,
                            Session.NamespaceUris,
                            Session.TypeTree);

                        if (typeInfo == null)
                        {
                            request.InputArguments[inputArguments.Count / 2] = arg;
                            methodsToCall.Add(request);
                            break;
                        }
                    }while (typeInfo != null);
                }
            }

            // add extra parameters.
            request = new CallMethodRequest();

            request.ObjectId       = method.Parent.NodeId;
            request.MethodId       = method.Method.NodeId;
            request.Handle         = method;
            request.InputArguments = new VariantCollection(inputArguments);
            request.InputArguments.Add(new Variant(m_generator.GetRandom(BuiltInType.Variant)));

            methodsToCall.Add(request);
        }
Esempio n. 12
0
        /// <summary>
        /// Reads the attributes, verifies the results and updates the nodes.
        /// </summary>
        private bool Call(CallMethodRequestCollection methodsToCall)
        {
            Opc.Ua.Test.DataComparer comparer = new Opc.Ua.Test.DataComparer(Session.MessageContext);

            bool success = true;

            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            RequestHeader requestHeader = new RequestHeader();

            requestHeader.ReturnDiagnostics = 0;

            try
            {
                Session.Call(
                    requestHeader,
                    methodsToCall,
                    out results,
                    out diagnosticInfos);
            }
            catch (System.ServiceModel.CommunicationException e)
            {
                Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message);
                return(true);
            }
            catch (System.Xml.XmlException e)
            {
                Log("WARNING: XML parsing error (random data may have resulted in a message that is too large). {0}", e.Message);
                return(true);
            }
            catch (ServiceResultException e)
            {
                if (e.StatusCode == StatusCodes.BadEncodingLimitsExceeded)
                {
                    Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message);
                    return(true);
                }

                throw new ServiceResultException(new ServiceResult(e));
            }

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

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

            // check results.
            for (int ii = 0; ii < methodsToCall.Count; ii++)
            {
                CallMethodRequest request = methodsToCall[ii];
                TestMethod        method  = (TestMethod)request.Handle;

                if (request.ObjectId != method.Parent.NodeId)
                {
                    if (results[ii].StatusCode != StatusCodes.BadMethodInvalid)
                    {
                        Log(
                            "Invalid result when method called on wrong object '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].StatusCode == StatusCodes.BadUserAccessDenied)
                {
                    if (method.Method.UserExecutable)
                    {
                        Log(
                            "Call failed when calling an executable method '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].StatusCode == StatusCodes.BadNotImplemented)
                {
                    continue;
                }

                if (request.InputArguments.Count != method.InputArguments.Count)
                {
                    if (results[ii].StatusCode != StatusCodes.BadArgumentsMissing)
                    {
                        Log(
                            "Incorrect error returned when passing method wrong number of arguments '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].StatusCode == StatusCodes.BadInvalidArgument || results[ii].StatusCode == StatusCodes.BadOutOfRange)
                {
                    if (results[ii].InputArgumentResults.Count != request.InputArguments.Count)
                    {
                        Log(
                            "Incorrect number of result returned when reporting argument error '{0}'. NodeId = {1}, Method = {2}, Expected = {3}, Actual = {4}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            request.InputArguments.Count,
                            results[ii].InputArgumentResults.Count);

                        success = false;
                        break;
                    }

                    bool errorFound = false;

                    for (int jj = 0; jj < method.InputArguments.Count; jj++)
                    {
                        if (results[ii].InputArgumentResults[jj] != results[ii].StatusCode)
                        {
                            errorFound = true;
                        }

                        Argument argument = method.InputArguments[jj];

                        // check if data type matches.
                        TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType(
                            request.InputArguments[jj].Value,
                            argument.DataType,
                            argument.ValueRank,
                            Session.NamespaceUris,
                            Session.TypeTree);

                        if (typeInfo == null)
                        {
                            if (results[ii].InputArgumentResults[jj] != StatusCodes.BadTypeMismatch)
                            {
                                Log(
                                    "Incorrect error returned for invalid argument '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, StatusCode = {4}",
                                    method.Parent,
                                    method.Parent.NodeId,
                                    method.Method,
                                    method.InputArguments[jj].Name,
                                    results[ii].InputArgumentResults[jj]);

                                success = false;
                            }

                            continue;
                        }

                        if (results[ii].InputArgumentResults[jj] != StatusCodes.Good && results[ii].InputArgumentResults[jj] != StatusCodes.BadOutOfRange)
                        {
                            Log(
                                "Incorrect error returned for valid argument '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, StatusCode = {4}",
                                method.Parent,
                                method.Parent.NodeId,
                                method.Method,
                                method.InputArguments[jj].Name,
                                results[ii].InputArgumentResults[jj]);

                            success = false;
                        }
                    }

                    if (!success)
                    {
                        break;
                    }

                    if (!errorFound)
                    {
                        Log(
                            "No matching argument level error for method '{0}'. NodeId = {1}, Method = {2}, StatusCode = {4}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    if (results[ii].StatusCode != StatusCodes.BadNotImplemented)
                    {
                        Log(
                            "Unexpected error when calling method '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].OutputArguments.Count != method.OutputArguments.Count)
                {
                    Log(
                        "Incorrect number of output arguments '{0}'. NodeId = {1}, Method = {2}, Expected = {3}, Actual = {4}",
                        method.Parent,
                        method.Parent.NodeId,
                        method.Method,
                        method.OutputArguments.Count,
                        results[ii].OutputArguments.Count);

                    success = false;
                    break;
                }

                for (int jj = 0; jj < method.OutputArguments.Count; jj++)
                {
                    Argument argument = method.OutputArguments[jj];

                    // check if data type matches.
                    TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType(
                        results[ii].OutputArguments[jj].Value,
                        argument.DataType,
                        argument.ValueRank,
                        Session.NamespaceUris,
                        Session.TypeTree);

                    if (typeInfo == null)
                    {
                        Log(
                            "Datatype for output argument is invalid '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, Value = {4}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            method.OutputArguments[jj].Name,
                            results[ii].OutputArguments[jj]);

                        success = false;
                        continue;
                    }

                    // check for special test methods that return the input parameters.
                    if (method.Parent.BrowseName.Name == "MethodTest")
                    {
                        if (jj < request.InputArguments.Count)
                        {
                            if (!comparer.CompareVariant(request.InputArguments[jj], results[ii].OutputArguments[jj]))
                            {
                                Log(
                                    "Output argument did not match input '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, Value = {4}, Output = {5}",
                                    method.Parent,
                                    method.Parent.NodeId,
                                    method.Method,
                                    method.OutputArguments[jj].Name,
                                    request.InputArguments[jj],
                                    results[ii].OutputArguments[jj]);

                                success = false;
                                continue;
                            }
                        }
                    }
                }

                if (!success)
                {
                    break;
                }
            }

            return(success);
        }
Esempio n. 13
0
        /// <summary>
        /// Adds random parameters
        /// </summary>
        private void AddMethodCall(
            TestMethod method, 
            CallMethodRequestCollection methodsToCall,
            bool testErrors)
        {            
            VariantCollection inputArguments = new VariantCollection();

            for (int ii = 0; ii < method.InputArguments.Count; ii++)
            {
                Argument argument = method.InputArguments[ii];

                object value = m_generator.GetRandom(
                    argument.DataType,
                    argument.ValueRank,
                    argument.ArrayDimensions,
                    Session.TypeTree);
                
                inputArguments.Add(new Variant(value));
            }
         
            CallMethodRequest request = null;

            // add valid method.
            if (!testErrors)
            {
                request = new CallMethodRequest();

                request.ObjectId = method.Parent.NodeId;
                request.MethodId = method.Method.NodeId;
                request.Handle = method;
                request.InputArguments = new VariantCollection(inputArguments);

                methodsToCall.Add(request);

                return;
            }
                     
            // add invalid object.
            request = new CallMethodRequest();

            request.ObjectId = Objects.RootFolder;
            request.MethodId = method.Method.NodeId;
            request.Handle = method;
            request.InputArguments = new VariantCollection(inputArguments);

            methodsToCall.Add(request);
                                 
            if (inputArguments.Count > 0)
            {
                // add too few parameters.
                request = new CallMethodRequest();

                request.ObjectId = method.Parent.NodeId;
                request.MethodId = method.Method.NodeId;
                request.Handle = method;
                request.InputArguments = new VariantCollection(inputArguments);
                request.InputArguments.RemoveAt(request.InputArguments.Count-1);

                methodsToCall.Add(request);
                
                // add invalid parameter.
                request = new CallMethodRequest();

                request.ObjectId = method.Parent.NodeId;
                request.MethodId = method.Method.NodeId;
                request.Handle = method;
                request.InputArguments = new VariantCollection(inputArguments);
                
                Argument argument = method.InputArguments[inputArguments.Count/2];      
          
                if (TypeInfo.GetBuiltInType(argument.DataType, Session.TypeTree) != BuiltInType.Variant)
                {
                    TypeInfo typeInfo = null;

                    do
                    { 
                        Variant arg = (Variant)m_generator.GetRandom(BuiltInType.Variant);

                        typeInfo = TypeInfo.IsInstanceOfDataType(
                            arg.Value,
                            argument.DataType,
                            argument.ValueRank,
                            Session.NamespaceUris,
                            Session.TypeTree);

                        if (typeInfo == null)
                        {
                            request.InputArguments[inputArguments.Count/2] = arg;
                            methodsToCall.Add(request);
                            break;
                        }
                    }
                    while (typeInfo != null);
                }
            }

            // add extra parameters.
            request = new CallMethodRequest();

            request.ObjectId = method.Parent.NodeId;
            request.MethodId = method.Method.NodeId;
            request.Handle = method;
            request.InputArguments = new VariantCollection(inputArguments);
            request.InputArguments.Add(new Variant(m_generator.GetRandom(BuiltInType.Variant)));

            methodsToCall.Add(request);
        }
Esempio n. 14
0
        /// <summary>
        /// Calls the specified method and returns the output arguments.
        /// </summary>
        /// <param name="objectId">The NodeId of the object that provides the method.</param>
        /// <param name="methodId">The NodeId of the method to call.</param>
        /// <param name="args">The input arguments.</param>
        /// <returns>The list of output argument values.</returns>
        public IList<object> Call(NodeId objectId, NodeId methodId, params object[] args)
        {
            VariantCollection inputArguments = new VariantCollection();
            
            if (args != null)
            {
                for (int ii = 0; ii < args.Length; ii++)
                {
                    inputArguments.Add(new Variant(args[ii]));
                }
            }
                                            
            CallMethodRequest request = new CallMethodRequest();

            request.ObjectId       = objectId;
            request.MethodId       = methodId;
            request.InputArguments = inputArguments;

            CallMethodRequestCollection requests = new CallMethodRequestCollection();
            requests.Add(request);

            CallMethodResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            ResponseHeader responseHeader = Call(
                null,
                requests,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, requests);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, requests);
            
            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable);
            }

            List<object> outputArguments = new List<object>();

            foreach (Variant arg in results[0].OutputArguments)
            {
                outputArguments.Add(arg.Value);
            }

            return outputArguments;
        }
Esempio n. 15
0
        /// <summary>
        /// Acknowledges one or more events.
        /// </summary>
        public int[] AcknowledgeEvents(
            Session session,
            string comment,
            string acknowledgerId,
            AeAcknowledgeRequest[] requests)
        {
            if (session == null || !session.Connected)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            StringBuilder buffer = new StringBuilder();
            buffer.Append('[');
            buffer.Append(acknowledgerId);
            buffer.Append(']');

            if (!String.IsNullOrEmpty(comment))
            {
                buffer.Append(comment);
            }

            // wrap the comment once.
            Variant commentToWrite = new Variant(new LocalizedText(buffer.ToString()));

            int[] errors = new int[requests.Length];
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < requests.Length; ii++)
            {
                int cookie = requests[ii].Cookie;

                AeEvent e = null;

                lock (m_lock)
                {
                    // look up the event.
                    if (!m_events.TryGetValue(cookie, out e))
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;

                        if (cookie < m_counter)
                        {
                            errors[ii] = ResultIds.S_ALREADYACKED;
                        }
                        
                        continue;
                    }
                    
                    if (e.SourceName != requests[ii].SourceName)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    if (e.ConditionName != requests[ii].ConditionName)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    if (e.ActiveTime != requests[ii].ActiveTime)
                    {
                        errors[ii] = ResultIds.E_INVALIDTIME;
                        continue;
                    }
                    
                    // check that the cookie is still valid.
                    string conditionId = GetConditionId(e);
                    int expectedCookie = 0;

                    if (!m_cookies.TryGetValue(conditionId, out expectedCookie))
                    {
                        errors[ii] = ResultIds.S_ALREADYACKED;
                        continue;
                    }

                    // check cookie.
                    if (expectedCookie != cookie)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    m_events.Remove(cookie);
                }

                CallMethodRequest request = new CallMethodRequest();
                request.MethodId = Opc.Ua.MethodIds.AcknowledgeableConditionType_Acknowledge;
                request.ObjectId = e.ConditionId;
                request.InputArguments.Add(new Variant(e.EventId));
                request.InputArguments.Add(commentToWrite);
                request.Handle = ii;
                methodsToCall.Add(request);
            }

            if (methodsToCall.Count > 0)
            {
                try
                {
                    // call the server.
                    CallMethodResultCollection results = null;
                    DiagnosticInfoCollection diagnosticInfos = null;

                    session.Call(
                        null,
                        methodsToCall,
                        out results,
                        out diagnosticInfos);

                    // verify that the server returned the correct number of results.
                    ClientBase.ValidateResponse(results, methodsToCall);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

                    // process results.
                    for (int ii = 0; ii < methodsToCall.Count; ii++)
                    {
                        int index = (int)methodsToCall[ii].Handle;

                        if (StatusCode.IsBad(results[ii].StatusCode))
                        {
                            errors[ii] = ResultIds.E_FAIL;
                            continue;
                        }
                    }
                }
                catch (Exception)
                {
                    // report error.
                    for (int ii = 0; ii < methodsToCall.Count; ii++)
                    {
                        int index = (int)methodsToCall[ii].Handle;
                        errors[ii] = ResultIds.E_FAIL;
                    }
                }
            }

            return errors;
        }
Esempio n. 16
0
        /// <summary>
        /// Confirms the selected conditions.
        /// </summary>
        private void Shelve(bool shelving, bool oneShot, double shelvingTime)
        {
            // build list of methods to call.
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++)
            {
                ConditionState condition = (ConditionState)ConditionsLV.SelectedItems[ii].Tag;

                // check if the node supports shelving.
                BaseObjectState shelvingState = condition.FindChild(m_session.SystemContext, BrowseNames.ShelvingState) as BaseObjectState;

                if (shelvingState == null)
                {
                    continue;
                }

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = shelvingState.NodeId;
                request.Handle   = ConditionsLV.SelectedItems[ii];

                // select the method to call.
                if (!shelving)
                {
                    request.MethodId = MethodIds.ShelvedStateMachineType_Unshelve;
                }
                else
                {
                    if (oneShot)
                    {
                        request.MethodId = MethodIds.ShelvedStateMachineType_OneShotShelve;
                    }
                    else
                    {
                        request.MethodId = MethodIds.ShelvedStateMachineType_TimedShelve;
                        request.InputArguments.Add(new Variant(shelvingTime));
                    }
                }

                methodsToCall.Add(request);
            }

            if (methodsToCall.Count == 0)
            {
                return;
            }

            // call the methods.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

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

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ListViewItem item = (ListViewItem)methodsToCall[ii].Handle;
                    item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode);
                }
            }
        }
        /// <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;
        }
Esempio n. 18
0
        /// <summary>
        /// Returns the list of published nodes of the OPC UA server with the given endpointUrl
        /// </summary>
        private async Task <string[]> GetPublishedNodes(string endpointUrl)
        {
            List <string> publishedNodes     = new List <string>();
            Session       publisherSession   = null;
            string        publisherSessionId = Guid.NewGuid().ToString();

            // read the published nodes from the publisher
            try
            {
                try
                {
                    publisherSession = await ConnectToPublisher(publisherSessionId);
                }
                catch
                {
                    return(null);
                }

                if (publisherSession != null)
                {
                    VariantCollection inputArguments = new VariantCollection();
                    Variant           endpointUrlValue;
                    try
                    {
                        OpcSessionHelper.Instance.BuildDataValue(ref publisherSession, ref endpointUrlValue, TypeInfo.GetDataTypeId(string.Empty), ValueRanks.Scalar, endpointUrl);
                    }
                    catch (Exception e)
                    {
                        return(null);
                    }
                    inputArguments.Add(endpointUrlValue);

                    bool retry = true;
                    while (true)
                    {
                        try
                        {
                            CallMethodRequestCollection requests = new CallMethodRequestCollection();
                            CallMethodResultCollection  results;
                            DiagnosticInfoCollection    diagnosticInfos = null;
                            CallMethodRequest           request         = new CallMethodRequest();
                            request.ObjectId       = new NodeId("Methods", 2);
                            request.MethodId       = new NodeId("GetPublishedNodes", 2);
                            request.InputArguments = inputArguments;
                            requests.Add(request);
                            ResponseHeader responseHeader = publisherSession.Call(null, requests, out results, out diagnosticInfos);
                            if (StatusCode.IsBad(results[0].StatusCode))
                            {
                                return(null);
                            }
                            else
                            {
                                if (results?[0]?.OutputArguments.Count == 1)
                                {
                                    string stringResult = results[0].OutputArguments[0].ToString();

                                    int jsonStartIndex = stringResult.IndexOf("[");
                                    int jsonEndIndex   = stringResult.IndexOf("]");
                                    PublishedNodesCollection nodelist = JsonConvert.DeserializeObject <PublishedNodesCollection>(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1));
                                    foreach (NodeLookup node in nodelist)
                                    {
                                        publishedNodes.Add(node.NodeID.ToString());
                                    }

                                    return(publishedNodes.ToArray());
                                }
                                else
                                {
                                    return(null);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            if (!retry)
                            {
                                return(null);
                            }
                            retry = false;
                        }
                    }
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception e)
            {
                return(null);
            }
            finally
            {
                if (publisherSession != null)
                {
                    OpcSessionHelper.Instance.Disconnect(publisherSessionId);
                }
            }
        }
Esempio n. 19
0
        public NodeHandle FindBranchNodeHandle(ISystemContext systemContext, NodeHandle initialHandle, CallMethodRequest methodToCall)
        {
            NodeHandle nodeHandle = initialHandle;

            if (IsAckConfirm(methodToCall.MethodId))
            {
                AlarmHolder holder = GetAlarmHolder(methodToCall.ObjectId);

                if (holder != null)
                {
                    if (holder.HasBranches())
                    {
                        byte[] eventId = GetEventIdFromAckConfirmMethod(methodToCall);

                        if (eventId != null)
                        {
                            BaseEventState state = holder.GetBranch(eventId);

                            if (state != null)
                            {
                                nodeHandle = new NodeHandle();

                                nodeHandle.NodeId    = methodToCall.ObjectId;
                                nodeHandle.Node      = state;
                                nodeHandle.Validated = true;
                            }
                        }
                    }
                }
            }

            return(nodeHandle);
        }
Esempio n. 20
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);
            }
        }
Esempio n. 21
0
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                VariantCollection inputArguments = InputArgumentsCTRL.GetValues();
                                
                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId       = m_objectId;
                request.MethodId       = m_methodId;
                request.InputArguments = inputArguments;

                CallMethodRequestCollection requests = new CallMethodRequestCollection();
                requests.Add(request);

                CallMethodResultCollection results;
                DiagnosticInfoCollection diagnosticInfos;

                ResponseHeader responseHeader = m_session.Call(
                    null,
                    requests,
                    out results,
                    out diagnosticInfos);

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable));
                }

                OutputArgumentsCTRL.SetValues(results[0].OutputArguments);

                if (results[0].OutputArguments.Count == 0)
                {
                    MessageBox.Show(this, "Method executed successfully.");
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Acknowledges one or more events.
        /// </summary>
        public int[] AcknowledgeEvents(
            Session session,
            string comment,
            string acknowledgerId,
            AeAcknowledgeRequest[] requests)
        {
            if (session == null || !session.Connected)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            StringBuilder buffer = new StringBuilder();

            buffer.Append('[');
            buffer.Append(acknowledgerId);
            buffer.Append(']');

            if (!String.IsNullOrEmpty(comment))
            {
                buffer.Append(comment);
            }

            // wrap the comment once.
            Variant commentToWrite = new Variant(new LocalizedText(buffer.ToString()));

            int[] errors = new int[requests.Length];
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < requests.Length; ii++)
            {
                int cookie = requests[ii].Cookie;

                AeEvent e = null;

                lock (m_lock)
                {
                    // look up the event.
                    if (!m_events.TryGetValue(cookie, out e))
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;

                        if (cookie < m_counter)
                        {
                            errors[ii] = ResultIds.S_ALREADYACKED;
                        }

                        continue;
                    }

                    if (e.SourceName != requests[ii].SourceName)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    if (e.ConditionName != requests[ii].ConditionName)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    if (e.ActiveTime != requests[ii].ActiveTime)
                    {
                        errors[ii] = ResultIds.E_INVALIDTIME;
                        continue;
                    }

                    // check that the cookie is still valid.
                    string conditionId    = GetConditionId(e);
                    int    expectedCookie = 0;

                    if (!m_cookies.TryGetValue(conditionId, out expectedCookie))
                    {
                        errors[ii] = ResultIds.S_ALREADYACKED;
                        continue;
                    }

                    // check cookie.
                    if (expectedCookie != cookie)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    m_events.Remove(cookie);
                }

                CallMethodRequest request = new CallMethodRequest();
                request.MethodId = Opc.Ua.MethodIds.AcknowledgeableConditionType_Acknowledge;
                request.ObjectId = e.ConditionId;
                request.InputArguments.Add(new Variant(e.EventId));
                request.InputArguments.Add(commentToWrite);
                request.Handle = ii;
                methodsToCall.Add(request);
            }

            if (methodsToCall.Count > 0)
            {
                try
                {
                    // call the server.
                    CallMethodResultCollection results         = null;
                    DiagnosticInfoCollection   diagnosticInfos = null;

                    session.Call(
                        null,
                        methodsToCall,
                        out results,
                        out diagnosticInfos);

                    // verify that the server returned the correct number of results.
                    ClientBase.ValidateResponse(results, methodsToCall);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

                    // process results.
                    for (int ii = 0; ii < methodsToCall.Count; ii++)
                    {
                        int index = (int)methodsToCall[ii].Handle;

                        if (StatusCode.IsBad(results[ii].StatusCode))
                        {
                            errors[ii] = ResultIds.E_FAIL;
                            continue;
                        }
                    }
                }
                catch (Exception)
                {
                    // report error.
                    for (int ii = 0; ii < methodsToCall.Count; ii++)
                    {
                        int index = (int)methodsToCall[ii].Handle;
                        errors[ii] = ResultIds.E_FAIL;
                    }
                }
            }

            return(errors);
        }
Esempio n. 23
0
        /// <summary>
        /// Validates a call request item parameter
        /// </summary>
        protected static ServiceResult ValidateCallRequestItem(CallMethodRequest item)
        {
            // check for null structure.
            if (item == null)
            {
                return StatusCodes.BadStructureMissing;
            }

            // check object id.
            if (NodeId.IsNull(item.ObjectId))
            {
                return StatusCodes.BadNodeIdInvalid;
            }

            // check method id.
            if (NodeId.IsNull(item.MethodId))
            {
                return StatusCodes.BadMethodInvalid;
            }

            // check input arguments
            if (item.InputArguments == null)
            {
                return StatusCodes.BadStructureMissing;
            }

            // passed basic validation.
            return null;
        }
Esempio n. 24
0
        public async Task <ActionResult> VariablePublishUnpublish(string jstreeNode, string method)
        {
            string[] delimiter       = { "__$__" };
            string[] jstreeNodeSplit = jstreeNode.Split(delimiter, 3, StringSplitOptions.None);
            string   node;
            string   actionResult = "";
            Session  publisherSession;
            string   publisherSessionId = Guid.NewGuid().ToString();

            if (jstreeNodeSplit.Length == 1)
            {
                node = jstreeNodeSplit[0];
            }
            else
            {
                node = jstreeNodeSplit[1];
            }

            try
            {
                try
                {
                    publisherSession = await ConnectToPublisher(publisherSessionId);
                }
                catch
                {
                    return(Content(CreateOpcExceptionActionString(new Exception(Strings.Error))));
                }

                if (publisherSession != null)
                {
                    VariantCollection inputArguments = new VariantCollection();
                    Variant           nodeIdValue;
                    Variant           endpointUrlValue;
                    try
                    {
                        OpcSessionHelper.Instance.BuildDataValue(ref publisherSession, ref nodeIdValue, TypeInfo.GetDataTypeId(string.Empty), ValueRanks.Scalar, node);
                        OpcSessionHelper.Instance.BuildDataValue(ref publisherSession, ref endpointUrlValue, TypeInfo.GetDataTypeId(string.Empty), ValueRanks.Scalar, (string)Session["EndpointUrl"]);
                    }
                    catch (Exception exception)
                    {
                        actionResult = string.Format(Strings.BrowserOpcWriteConversionProblem, exception.Message);
                        return(Content(actionResult));
                    }
                    inputArguments.Add(nodeIdValue);
                    inputArguments.Add(endpointUrlValue);

                    bool retry = true;
                    while (true)
                    {
                        try
                        {
                            CallMethodRequestCollection requests = new CallMethodRequestCollection();
                            CallMethodResultCollection  results;
                            DiagnosticInfoCollection    diagnosticInfos = null;
                            CallMethodRequest           request         = new CallMethodRequest();
                            request.ObjectId = new NodeId("Methods", 2);
                            if (method == "unpublish")
                            {
                                request.MethodId = new NodeId("UnpublishNode", 2);
                            }
                            else
                            {
                                request.MethodId = new NodeId("PublishNode", 2);
                            }
                            request.InputArguments = inputArguments;
                            requests.Add(request);
                            ResponseHeader responseHeader = publisherSession.Call(null, requests, out results, out diagnosticInfos);
                            if (StatusCode.IsBad(results[0].StatusCode))
                            {
                                actionResult = Strings.BrowserOpcMethodCallFailed + @"<br/><br/>" +
                                               Strings.BrowserOpcMethodStatusCode + ": " + results[0].StatusCode;
                                if (diagnosticInfos.Count > 0)
                                {
                                    actionResult += @"<br/><br/>" + Strings.BrowserOpcDataDiagnosticInfoLabel + ": " + diagnosticInfos;
                                }
                            }
                            else
                            {
                                if (results[0].OutputArguments.Count == 0)
                                {
                                    actionResult = Strings.BrowserOpcMethodCallSucceeded;
                                }
                                else
                                {
                                    actionResult = Strings.BrowserOpcMethodCallSucceededWithResults + @"<br/><br/>";
                                    for (int ii = 0; ii < results[0].OutputArguments.Count; ii++)
                                    {
                                        actionResult += results[0].OutputArguments[ii] + "@<br/>";
                                    }
                                }
                            }
                            return(Content(actionResult));
                        }
                        catch (Exception exception)
                        {
                            if (!retry)
                            {
                                try
                                {
                                    OpcSessionHelper.Instance.Disconnect(publisherSessionId);
                                }
                                catch
                                {
                                }
                                return(Content(CreateOpcExceptionActionString(exception)));
                            }
                            retry = false;
                        }
                    }
                }
                else
                {
                    throw new Exception(Strings.SessionNull);
                }
            }
            catch (Exception exception)
            {
                return(Content(CreateOpcExceptionActionString(exception)));
            }
            finally
            {
                if (publisherSessionId != null)
                {
                    OpcSessionHelper.Instance.Disconnect(publisherSessionId);
                }
            }
        }
        protected override bool UnpublishAllConfiguredNodes(CancellationToken ct)
        {
            string logPrefix = $"{_logClassPrefix}:UnpublishAllConfiguredNodes:";
            List <PublisherConfigurationFileEntryLegacyModel> configFileEntries = null;
            bool result = true;

            VariantCollection inputArgumentsTestserver = new VariantCollection()
            {
                TestserverUrl
            };

            try
            {
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = new CallMethodResultCollection();
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest
                {
                    ObjectId = new NodeId("Methods", 2),
                    MethodId = new NodeId("GetPublishedNodes", 2),
                };
                request.InputArguments = inputArgumentsTestserver;
                requests.Add(request);
                try
                {
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, $"{logPrefix} Exception");
                }
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'");
                }
                else
                {
                    if (results?[0]?.OutputArguments.Count == 1)
                    {
                        string stringResult   = results[0].OutputArguments[0].ToString();
                        int    jsonStartIndex = stringResult.IndexOf("[", StringComparison.InvariantCulture);
                        int    jsonEndIndex   = stringResult.IndexOf("]", StringComparison.InvariantCulture);

                        configFileEntries = JsonConvert.DeserializeObject <List <PublisherConfigurationFileEntryLegacyModel> >(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1));

                        foreach (var configFileEntry in configFileEntries)
                        {
                            if (configFileEntry.OpcNodes == null)
                            {
                                result &= UnpublishOneNode(new NodeIdInfo(configFileEntry.NodeId.ToString()));
                            }
                            else
                            {
                                foreach (var node in configFileEntry.OpcNodes)
                                {
                                    result &= UnpublishOneNode(new NodeIdInfo(node.Id), configFileEntry.EndpointUrl.AbsoluteUri);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            return(result);
        }
        public async Task <ActionResult> MethodCall(string jstreeNode, string parameterData, string parameterValues, Session session = null)
        {
            string[] delimiter       = { "__$__" };
            string[] jstreeNodeSplit = jstreeNode.Split(delimiter, 3, StringSplitOptions.None);
            string   node;
            string   parentNode = null;

            if (jstreeNodeSplit.Length == 1)
            {
                node       = jstreeNodeSplit[0];
                parentNode = null;
            }
            else
            {
                node       = jstreeNodeSplit[1];
                parentNode = (jstreeNodeSplit[0].Replace(delimiter[0], "")).Replace("__", "");
            }

            string actionResult = "";
            List <MethodCallParameterData> originalData = JsonConvert.DeserializeObject <List <MethodCallParameterData> >(parameterData);
            List <Variant>    values         = JsonConvert.DeserializeObject <List <Variant> >(parameterValues);
            int               count          = values.Count;
            VariantCollection inputArguments = new VariantCollection();

            bool retry = true;

            while (true)
            {
                try
                {
                    if (session == null)
                    {
                        session = await OpcSessionHelper.Instance.GetSessionAsync(Session.SessionID, (string)Session["EndpointUrl"]);
                    }

                    for (int i = 0; i < count; i++)
                    {
                        Variant value          = new Variant();
                        NodeId  dataTypeNodeId = "i=" + originalData[i].Datatype;
                        string  dataTypeName   = originalData[i].TypeName;
                        Int32   valueRank      = Convert.ToInt32(originalData[i].ValueRank, CultureInfo.InvariantCulture);
                        string  newValue       = values[i].Value.ToString();

                        try
                        {
                            OpcSessionHelper.Instance.BuildDataValue(ref session, ref value, dataTypeNodeId, valueRank, newValue);
                            inputArguments.Add(value);
                        }
                        catch (Exception exception)
                        {
                            actionResult = string.Format(Strings.BrowserOpcWriteConversionProblem, newValue,
                                                         dataTypeName, exception.Message);
                            return(Content(actionResult));
                        }
                    }

                    CallMethodRequestCollection requests = new CallMethodRequestCollection();
                    CallMethodResultCollection  results;
                    DiagnosticInfoCollection    diagnosticInfos = null;
                    CallMethodRequest           request         = new CallMethodRequest();
                    request.ObjectId       = new NodeId(parentNode);
                    request.MethodId       = new NodeId(node);
                    request.InputArguments = inputArguments;
                    requests.Add(request);
                    ResponseHeader responseHeader = session.Call(null, requests, out results, out diagnosticInfos);
                    if (StatusCode.IsBad(results[0].StatusCode))
                    {
                        actionResult = Strings.BrowserOpcMethodCallFailed + @"<br/><br/>" +
                                       Strings.BrowserOpcMethodStatusCode + ": " + results[0].StatusCode;
                        if (diagnosticInfos.Count > 0)
                        {
                            actionResult += @"<br/><br/>" + Strings.BrowserOpcDataDiagnosticInfoLabel + ": " + diagnosticInfos;
                        }
                    }
                    else
                    {
                        if (results[0].OutputArguments.Count == 0)
                        {
                            actionResult = Strings.BrowserOpcMethodCallSucceeded;
                        }
                        else
                        {
                            actionResult = Strings.BrowserOpcMethodCallSucceededWithResults + @"<br/><br/>";
                            for (int ii = 0; ii < results[0].OutputArguments.Count; ii++)
                            {
                                actionResult += results[0].OutputArguments[ii] + "@<br/>";
                            }
                        }
                    }
                    return(Content(actionResult));
                }
                catch (Exception exception)
                {
                    if (!retry)
                    {
                        return(Content(CreateOpcExceptionActionString(exception)));
                    }
                    retry = false;
                }
            }
        }
Esempio n. 27
0
        private string CallOpcMethod(string appUri, string parentNode, string methodNode)
        {
            string            result         = null;
            VariantCollection inputArguments = new VariantCollection();

            try
            {
                string  sessionID = Guid.NewGuid().ToString();
                Session session   = OpcSessionHelper.Instance.GetSessionWithImplicitTrust(sessionID, appUri).Result;
                if (session == null)
                {
                    result = $"Could not establish session to OPC UA server with appUri '{appUri}'";
                    Trace.TraceError(result);
                    return(result);
                }

                CallMethodRequestCollection requests = new CallMethodRequestCollection();
                CallMethodResultCollection  results;
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest();
                request.ObjectId       = new NodeId(parentNode);
                request.MethodId       = new NodeId(methodNode);
                request.InputArguments = inputArguments;
                requests.Add(request);
                ResponseHeader responseHeader = session.Call(null, requests, out results, out diagnosticInfos);
                OpcSessionHelper.Instance.Disconnect(sessionID);
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    result = Strings.BrowserOpcMethodCallFailed + "`n" +
                             Strings.BrowserOpcMethodStatusCode + ": " + results[0].StatusCode + "`n";
                    if (diagnosticInfos.Count > 0)
                    {
                        result += "`n" + Strings.BrowserOpcDataDiagnosticInfoLabel + ": " + diagnosticInfos;
                    }
                    Trace.TraceInformation($"OPC UA method call to OPC UA server '{appUri}' method '{methodNode}' under parent node '{parentNode}' failed.");
                    Trace.TraceInformation($"Details: {result}'");
                }
                else
                {
                    if (results[0].OutputArguments.Count == 0)
                    {
                        result = Strings.BrowserOpcMethodCallSucceeded;
                    }
                    else
                    {
                        result = Strings.BrowserOpcMethodCallSucceededWithResults + "`n";
                        for (int ii = 0; ii < results[0].OutputArguments.Count; ii++)
                        {
                            result += results[0].OutputArguments[ii] + "`n";
                        }
                    }
                    Trace.TraceInformation($"OPC UA method call to OPC UA server '{appUri}' method '{methodNode}' under parent node '{parentNode}' succeeded.");
                    Trace.TraceInformation($"Details: {result}'");
                }
            }
            catch (Exception exception)
            {
                result = $"Exception while calling OPC UA method: {exception.Message}";
            }
            return(result);
        }
        /// <summary>
        /// Calls the method.
        /// </summary>
        public void Call()
        {
            // build list of methods to call.
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            CallMethodRequest methodToCall = new CallMethodRequest();

            methodToCall.ObjectId = m_objectId;
            methodToCall.MethodId = m_methodId;

            foreach (DataRow row in m_dataset.Tables[0].Rows)
            {
                Argument argument = (Argument)row[0];
                Variant  value    = (Variant)row[4];
                argument.Value = value.Value;
                methodToCall.InputArguments.Add(value);
            }

            methodsToCall.Add(methodToCall);

            // call the method.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            ResponseHeader responseHeader = m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

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

            for (int ii = 0; ii < results.Count; ii++)
            {
                // display any input argument errors.
                if (results[ii].InputArgumentResults != null)
                {
                    for (int jj = 0; jj < results[ii].InputArgumentResults.Count; jj++)
                    {
                        if (StatusCode.IsBad(results[ii].InputArgumentResults[jj]))
                        {
                            DataRow row = m_dataset.Tables[0].Rows[jj];
                            row[5]           = results[ii].InputArgumentResults[jj].ToString();
                            ResultCH.Visible = true;
                        }
                    }
                }

                // throw an exception on error.
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    throw ServiceResultException.Create(results[ii].StatusCode, ii, diagnosticInfos, responseHeader.StringTable);
                }

                // display the output arguments
                ResultCH.Visible      = false;
                NoArgumentsLB.Visible = m_outputArguments == null || m_outputArguments.Length == 0;
                NoArgumentsLB.Text    = "Method invoked successfully.\r\nNo output arguments to display.";
                m_dataset.Tables[0].Rows.Clear();

                if (m_outputArguments != null)
                {
                    for (int jj = 0; jj < m_outputArguments.Length; jj++)
                    {
                        DataRow row = m_dataset.Tables[0].NewRow();

                        if (results[ii].OutputArguments.Count > jj)
                        {
                            UpdateRow(row, m_outputArguments[jj], results[ii].OutputArguments[jj], true);
                        }
                        else
                        {
                            UpdateRow(row, m_outputArguments[jj], Variant.Null, true);
                        }

                        m_dataset.Tables[0].Rows.Add(row);
                    }
                }
            }
        }
Esempio n. 29
0
        private async Task <Session> ConsoleSampleClient()
        {
            var application = new ApplicationInstance {
                ApplicationType = ApplicationType.Client
            };

            #region Create an Application Configuration
            Console.WriteLine(" 1 - Create an Application Configuration.");
            ExitCode = ExitCode.ErrorCreateApplication;

            // Load the Application Configuration and use the specified config section "Technosoftware.SimpleClient"
            var config = await application.LoadConfigurationAsync("Technosoftware.SimpleClient");

            // check the application certificate.
            var haveAppCertificate = await application.CheckApplicationInstanceCertificateAsync(false, CertificateFactory.DefaultKeySize, CertificateFactory.DefaultLifeTime);

            reverseConnectManager_ = null;
            if (ReverseConnectUri != null)
            {
                // start the reverse connection manager
                reverseConnectManager_ = new ReverseConnectManager();
                reverseConnectManager_.AddEndpoint(ReverseConnectUri);
                reverseConnectManager_.StartService(config);
            }

            if (haveAppCertificate)
            {
                config.ApplicationUri = X509Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);
                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    autoAccept_ = true;
                }
                config.CertificateValidator.CertificateValidation += OnCertificateValidation;
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecured connection.");
            }
            #endregion

            #region Discover endpoints
            Console.WriteLine(" 2 - Discover endpoints of {0}.", endpointUrl_);
            ExitCode = ExitCode.ErrorDiscoverEndpoints;
            EndpointDescription selectedEndpoint;
            if (reverseConnectManager_ == null)
            {
                selectedEndpoint = Discover.SelectEndpoint(endpointUrl_, haveAppCertificate && !SecurityNone, 15000);
            }
            else
            {
                Console.WriteLine("   Waiting for reverse connection.");
                var connection = await reverseConnectManager_.WaitForConnection(
                    new Uri(endpointUrl_), null, new CancellationTokenSource(60000).Token);

                if (connection == null)
                {
                    throw new ServiceResultException(StatusCodes.BadTimeout, "Waiting for a reverse connection timed out.");
                }
                selectedEndpoint = Discover.SelectEndpoint(config, connection, haveAppCertificate && !SecurityNone, 15000);
            }

            Console.WriteLine("    Selected endpoint uses: {0}",
                              selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));
            #endregion

            #region Create a session with OPC UA server
            Console.WriteLine(" 3 - Create a session with OPC UA server.");
            ExitCode = ExitCode.ErrorCreateSession;

            // create the user identity
            UserIdentity userIdentity;
            if (String.IsNullOrEmpty(Username) && String.IsNullOrEmpty(Password))
            {
                userIdentity = new UserIdentity(new AnonymousIdentityToken());
            }
            else
            {
                userIdentity = new UserIdentity(Username, Password);
            }

            // create worker session
            if (reverseConnectManager_ == null)
            {
                session_ = await CreateSessionAsync(config, selectedEndpoint, userIdentity).ConfigureAwait(false);
            }
            else
            {
                Console.WriteLine("   Waiting for reverse connection.");
                // Define the cancellation token.
                var source = new CancellationTokenSource(60000);
                var token  = source.Token;
                try
                {
                    var connection = await reverseConnectManager_.WaitForConnection(
                        new Uri(endpointUrl_), null, token);

                    if (connection == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadTimeout,
                                                         "Waiting for a reverse connection timed out.");
                    }

                    session_ = await CreateSessionAsync(config, connection, selectedEndpoint, userIdentity)
                               .ConfigureAwait(false);
                }
                finally
                {
                    source.Dispose();
                }
            }

            // register keep alive handler
            session_.SessionKeepAliveEvent += OnSessionKeepAliveEvent;
            #endregion

            #region Browse the OPC UA Server
            Console.WriteLine(" 4 - Browse address space.");
            // Create the browser
            var browser = new Browser(session_)
            {
                BrowseDirection   = BrowseDirection.Forward,
                ReferenceTypeId   = ReferenceTypeIds.HierarchicalReferences,
                IncludeSubtypes   = true,
                NodeClassMask     = 0,
                ContinueUntilDone = false
            };

            // Browse from the RootFolder
            var references = browser.Browse(Objects.ObjectsFolder);

            GetElements(session_, browser, 0, references, Verbose);

            #endregion

            #region Read a single value
            Console.WriteLine(" 5 - Read a single value.");
            var simulatedDataValue = session_.ReadValue(simulatedDataNodeId_);
            Console.WriteLine("Node Value:" + simulatedDataValue.Value);
            #endregion

            #region Read multiple values
            Console.WriteLine(" 6 - Read multiple values.");
            // The input parameters of the ReadValues() method
            var variableIds   = new List <NodeId>();
            var expectedTypes = new List <Type>();

            // Add a node to the list
            variableIds.Add(simulatedDataNodeId_);
            // Add an expected type to the list (null means we get the original type from the server)
            expectedTypes.Add(null);

            // Add another node to the list
            variableIds.Add(staticDataNodeId1_);
            // Add an expected type to the list (null means we get the original type from the server)
            expectedTypes.Add(null);

            // Add another node to the list
            variableIds.Add(staticDataNodeId2_);

            // Add an expected type to the list (null means we get the original type from the server)
            expectedTypes.Add(null);

            session_.ReadValues(variableIds, expectedTypes, out var values, out var errors);
            // write the result to the console.
            for (var i = 0; i < values.Count; i++)
            {
                Console.WriteLine("Status of Read of Node {0} is: {1}", variableIds[i].ToString(), errors[i]);
            }
            for (var i = 0; i < values.Count; i++)
            {
                Console.WriteLine("Value of Read of Node {0} is: Value: {1}", variableIds[i].ToString(), values[i]);
            }
            #endregion

            #region Read multiple values asynchronous
            Console.WriteLine(" 7 - Read multiple values asynchronous.");
            // start reading the value (setting a 10 second timeout).
            session_.BeginReadValues(
                variableIds,
                0,
                TimestampsToReturn.Both,
                OnReadComplete,
                new UserData {
                Session = session_, NodeIds = variableIds
            });
            #endregion

            #region Write a value
            Console.WriteLine(" 8 - Write a value.");
            short writeInt = 1234;

            Console.WriteLine("Write Value: " + writeInt);
            session_.WriteValue(staticDataNodeId1_, new DataValue(writeInt));

            // read it again to check the new value
            Console.WriteLine("Node Value (should be {0}): {1}", session_.ReadValue(staticDataNodeId1_).Value, writeInt);
            #endregion

            #region Write multiple values at once
            Console.WriteLine(" 9 - Write multiple values at once.");

            writeInt = 5678;
            var writeDouble = 1234.1234;

            var nodeIds    = new List <NodeId>();
            var dataValues = new List <DataValue>();

            nodeIds.Add(staticDataNodeId1_);
            nodeIds.Add(staticDataNodeId2_);

            dataValues.Add(new DataValue(writeInt));
            dataValues.Add(new DataValue(writeDouble));

            Console.WriteLine("Write Values: {0} and {1}", writeInt, writeDouble);
            var statusCodes = session_.WriteValues(nodeIds, dataValues);

            Console.WriteLine("Returned status codes:");
            foreach (var statusCode in statusCodes)
            {
                Console.WriteLine("Status: {0}", statusCode.ToString());
            }

            // read it again to check the new value
            Console.WriteLine("Node Value (should be {0}): {1}", session_.ReadValue(staticDataNodeId1_).Value, writeInt);
            Console.WriteLine("Node Value (should be {0}): {1}", session_.ReadValue(staticDataNodeId2_).Value, writeDouble);
            #endregion

            #region Write multiple values asynchronous
            Console.WriteLine("10 - Write multiple values asynchronous.");

            // start writing the values.
            session_.BeginWriteValues(
                nodeIds,
                dataValues,
                OnWriteComplete,
                new UserData {
                Session = session_, NodeIds = nodeIds
            });
            #endregion

            #region Call a Method
            Console.WriteLine("11 - Call a Method.");
            INode node = session_.ReadNode(callHelloMethodNodeId_);


            if (node is MethodNode)
            {
                var methodId = callHelloMethodNodeId_;

                var objectId = methodsNodeId_;

                var inputArguments = new VariantCollection {
                    new Variant("from Technosoftware")
                };

                var request = new CallMethodRequest {
                    ObjectId = objectId, MethodId = methodId, InputArguments = inputArguments
                };

                var requests = new CallMethodRequestCollection {
                    request
                };

                var responseHeader = session_.Call(
                    null,
                    requests,
                    out var results,
                    out var diagnosticInfos);

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos,
                                                                       responseHeader.StringTable));
                }

                Console.WriteLine("{0}", results[0].OutputArguments[0]);
            }

            #endregion

            #region Create a subscription with publishing interval of 1 second
            Console.WriteLine("12 - Create a subscription with publishing interval of 1 second.");
            ExitCode      = ExitCode.ErrorCreateSubscription;
            subscription_ = new Subscription(session_.DefaultSubscription)
            {
                PublishingInterval = 1000
            };
            #endregion

            #region Add all dynamic values and the server time to the subscription
            Console.WriteLine("13 - Add all dynamic values and the server time to the subscription.");
            ExitCode = ExitCode.ErrorMonitoredItem;
            var list = new List <MonitoredItem> {
                new MonitoredItem(subscription_.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime
                }
            };
            list.ForEach(i => i.MonitoredItemNotificationEvent += OnNotification);

            var newItem = new MonitoredItem(subscription_.DefaultItem)
            {
                DisplayName = "Simulated Data Value",
                StartNodeId = new NodeId(simulatedDataNodeId_)
            };
            newItem.MonitoredItemNotificationEvent += OnMonitoredItemNotificationEvent;
            list.Add(newItem);

            subscription_.AddItems(list);
            #endregion

            #region Add the subscription to the session
            Console.WriteLine("14 - Add the subscription to the session.");
            ExitCode = ExitCode.ErrorAddSubscription;
            session_.AddSubscription(subscription_);
            subscription_.Create();
            #endregion

            #region Running...Press Ctrl-C to exit...
            Console.WriteLine("15 - Running...Press Ctrl-C to exit...");
            ExitCode = ExitCode.ErrorRunning;
            #endregion

            return(session_);
        }