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)); }
/// <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); }
/// <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); } } }
/// <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); } } }
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); }
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); }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
/// <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); } } }
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); }
/// <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); } }
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); } }
/// <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); }
/// <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; }
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; } } }
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); } } } }
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_); }