public void WriteDict(Dictionary <string, ushort> valueDict) { using (var session = Session.Create(_config, new ConfiguredEndpoint(null, _endpointDesc, EndpointConfiguration.Create(_config)), false, "", 60000, null, null).GetAwaiter().GetResult()) { StatusCodeCollection results = null; DiagnosticInfoCollection infos = null; session.Write(null, GetWriteValueCollection(valueDict), out results, out infos); if (results.Any(sc => StatusCode.IsNotGood(sc))) { var messageBuilder = new StringBuilder(); for (int i = 0; i < results.Count; i++) { if (StatusCode.IsNotGood(results[i])) { messageBuilder.AppendLine($"{valueDict.ElementAt(i).Key}: {StatusCodes.GetBrowseName(results[i].Code)}"); } } throw new KepServerWriteException(messageBuilder.ToString()); } } }
private void UpdateBTN_Click(object sender, EventArgs e) { try { WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = m_variableId; nodeToWrite.AttributeId = Attributes.Value; nodeToWrite.Value = new DataValue(); nodeToWrite.Value.WrappedValue = GetValue(); WriteValueCollection nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(nodeToWrite); // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.Write( null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check for error. if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
// Original Features from the .NET Sample Client implementation, not needed for this OPC UA Client /* * public Tree GetRootNode(LabelViewModel textInfo) * { * ReferenceDescriptionCollection references; * Byte[] continuationPoint; * Tree browserTree = new Tree(); * * try * { * session.Browse( * null, * null, * ObjectIds.ObjectsFolder, * 0u, * BrowseDirection.Forward, * ReferenceTypeIds.HierarchicalReferences, * true, * 0, * out continuationPoint, * out references); * * browserTree.currentView.Add(new ListNode { id = ObjectIds.ObjectsFolder.ToString(), NodeName = "Root", children = (references?.Count != 0) }); * * return browserTree; * } * catch * { * Disconnect(session); * return null; * } * } * * public Tree GetChildren(string node) * { * ReferenceDescriptionCollection references; * Byte[] continuationPoint; * Tree browserTree = new Tree(); * * try * { * session.Browse( * null, * null, * node, * 0u, * BrowseDirection.Forward, * ReferenceTypeIds.HierarchicalReferences, * true, * 0, * out continuationPoint, * out references); * * if (references != null) * { * foreach (var nodeReference in references) * { * ReferenceDescriptionCollection childReferences = null; * Byte[] childContinuationPoint; * * session.Browse( * null, * null, * ExpandedNodeId.ToNodeId(nodeReference.NodeId, session.NamespaceUris), * 0u, * BrowseDirection.Forward, * ReferenceTypeIds.HierarchicalReferences, * true, * 0, * out childContinuationPoint, * out childReferences); * * INode currentNode = null; * try * { * currentNode = session.ReadNode(ExpandedNodeId.ToNodeId(nodeReference.NodeId, session.NamespaceUris)); * } * catch (Exception) * { * // skip this node * continue; * } * * byte currentNodeAccessLevel = 0; * byte currentNodeEventNotifier = 0; * bool currentNodeExecutable = false; * * VariableNode variableNode = currentNode as VariableNode; * if (variableNode != null) * { * currentNodeAccessLevel = variableNode.UserAccessLevel; * currentNodeAccessLevel = (byte)((uint)currentNodeAccessLevel & ~0x2); * } * * ObjectNode objectNode = currentNode as ObjectNode; * if (objectNode != null) * { * currentNodeEventNotifier = objectNode.EventNotifier; * } * * ViewNode viewNode = currentNode as ViewNode; * if (viewNode != null) * { * currentNodeEventNotifier = viewNode.EventNotifier; * } * * MethodNode methodNode = currentNode as MethodNode; * if (methodNode != null) * { * currentNodeExecutable = methodNode.UserExecutable; * } * * browserTree.currentView.Add(new ListNode() * { * id = nodeReference.NodeId.ToString(), * NodeName = nodeReference.DisplayName.Text.ToString(), * nodeClass = nodeReference.NodeClass.ToString(), * accessLevel = currentNodeAccessLevel.ToString(), * eventNotifier = currentNodeEventNotifier.ToString(), * executable = currentNodeExecutable.ToString(), * children = (references?.Count != 0), * ImageUrl = (nodeReference.NodeClass.ToString() == "Variable") ? "folderOpen.jpg" : "folder.jpg" * }); * if (browserTree.currentView[0].ImageUrl == null) * { * browserTree.currentView[0].ImageUrl = ""; * } * } * if (browserTree.currentView.Count == 0) * { * INode currentNode = session.ReadNode(new NodeId(node)); * * byte currentNodeAccessLevel = 0; * byte currentNodeEventNotifier = 0; * bool currentNodeExecutable = false; * * VariableNode variableNode = currentNode as VariableNode; * * if (variableNode != null) * { * currentNodeAccessLevel = variableNode.UserAccessLevel; * currentNodeAccessLevel = (byte)((uint)currentNodeAccessLevel & ~0x2); * } * * ObjectNode objectNode = currentNode as ObjectNode; * * if (objectNode != null) * { * currentNodeEventNotifier = objectNode.EventNotifier; * } * * ViewNode viewNode = currentNode as ViewNode; * * if (viewNode != null) * { * currentNodeEventNotifier = viewNode.EventNotifier; * } * * MethodNode methodNode = currentNode as MethodNode; * * if (methodNode != null ) * { * currentNodeExecutable = methodNode.UserExecutable; * } * * browserTree.currentView.Add(new ListNode() * { * id = node, * NodeName = currentNode.DisplayName.Text.ToString(), * nodeClass = currentNode.NodeClass.ToString(), * accessLevel = currentNodeAccessLevel.ToString(), * eventNotifier = currentNodeEventNotifier.ToString(), * executable = currentNodeExecutable.ToString(), * children = false, * ImageUrl = null * }); * } * } * return browserTree; * } * catch * { * Disconnect(session); * return null; * } * } */ #endregion #region custom VariableWrite Method /// <summary> /// Returns the ServiceResult from the ResponseHeader of the Variable Write Operation /// </summary> /// <param name="value">The int value that is to be written to the Node in the Server Namespace.</param> /// <param name="nodeId">The NodeId of the Node where the value shall be written.</param> public ResponseHeader VariableWrite(UInt16 value, string nodeId) { if (session != null) { if (session.Connected) { StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; // create a new WriteValueCollection (needed to call the Write Mehtod of the session) WriteValueCollection nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(new WriteValue { // NodeId of the Node to write NodeId = NodeId.Parse(nodeId), // We want to write the Value of the Node AttributeId = Attributes.Value, Value = new DataValue() { WrappedValue = value } }); // Actually write the Data. The method session.Write returns the responseHeader of the Write request response which is passed as the return value of this Method (VariableWrite) ResponseHeader responseHeader = session.Write(null, nodesToWrite, out results, out diagnosticInfos); return(responseHeader); } else { return(null); } } else { return(null); } }
public static void write() { WriteValue value = new WriteValue(); value.NodeId = Data.tags["DigitConst"].NodeId; value.AttributeId = Attributes.Value; value.Value.Value = 10; WriteValueCollection valuesToWrite = new WriteValueCollection(); valuesToWrite.Add(value); StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } }
private void WriteValue(Session session, NodeId variableId, DataValue value) { WriteValue nodeToWrite = new WriteValue { NodeId = variableId, AttributeId = Attributes.Value, Value = new DataValue { WrappedValue = value.WrappedValue } }; WriteValueCollection nodesToWrite = new WriteValueCollection { nodeToWrite }; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Write( null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check for error. if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <returns></returns> public string VariableWrite(string node, int value) { try { StatusCodeCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; //WriteValueIdCollection nodesToRead = new WriteValueIdCollection(); WriteValueCollection nodesToWrite = new WriteValueCollection(); WriteValue valueId = new WriteValue(); valueId.NodeId = new NodeId(node); valueId.AttributeId = Attributes.Value; valueId.IndexRange = null; valueId.Value = new DataValue(value); nodesToWrite.Add(valueId); ResponseHeader response = session.Write(null, nodesToWrite, out values, out diagnosticInfos); /*string value = ""; * if (values[0].Value != null) * { * var rawValue = values[0].WrappedValue.ToString(); * value = rawValue.Replace("|", "\r\n").Replace("{", "").Replace("}", ""); * }*/ return(null); } catch { return(null); } }
public void DeleteReferencesAsync() { var referencesToDelete = new DeleteReferencesItemCollection(); var deleteReferencesItem = new DeleteReferencesItem() { }; for (int ii = 0; ii < kOperationLimit * 2; ii++) { referencesToDelete.Add(deleteReferencesItem); } var requestHeader = new RequestHeader(); var sre = Assert.ThrowsAsync <ServiceResultException>(async() => { var response = await Session.DeleteReferencesAsync(requestHeader, referencesToDelete, CancellationToken.None).ConfigureAwait(false); StatusCodeCollection results = response.Results; DiagnosticInfoCollection diagnosticInfos = response.DiagnosticInfos; Assert.NotNull(response.ResponseHeader); Assert.AreEqual(referencesToDelete.Count, results.Count); Assert.AreEqual(diagnosticInfos.Count, diagnosticInfos.Count); }); Assert.AreEqual(StatusCodes.BadServiceUnsupported, sre.StatusCode); }
/// <summary> /// Creates a collection of status codes and diagnostics from a set of errors. /// </summary> public static StatusCodeCollection CreateStatusCodeCollection( OperationContext context, IList <ServiceResult> errors, out DiagnosticInfoCollection diagnosticInfos) { diagnosticInfos = null; bool noErrors = true; StatusCodeCollection results = new StatusCodeCollection(errors.Count); foreach (ServiceResult error in errors) { if (ServiceResult.IsBad(error)) { results.Add(error.Code); noErrors = false; } else { results.Add(StatusCodes.Good); } } // only generate diagnostics if errors exist. if (noErrors) { diagnosticInfos = CreateDiagnosticInfoCollection(context, errors); } return(results); }
public static void Execute(IEnumerable <DataItem> OPCItems, Session session) { log.Info("Writing DataItem Values."); try { StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; WriteValueCollection valuesToWrite = CreateWriteValueCollection(OPCItems); session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw new ServiceResultException(results[0]); } } catch (Exception exception) { log.Error("OPC Error Writing Value", exception); } }
public ResponseHeader CoreWrite(WriteValueCollection values, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { return(session.Write( null, values, out results, out diagnosticInfos)); }
public ResponseHeader DeleteSubscriptions( RequestHeader requestHeader, UInt32Collection subscriptionIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { return(m_session.DeleteSubscriptions(requestHeader, subscriptionIds, out results, out diagnosticInfos)); }
public ResponseHeader SetPublishingMode( RequestHeader requestHeader, bool publishingEnabled, UInt32Collection subscriptionIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { return(m_session.SetPublishingMode(requestHeader, publishingEnabled, subscriptionIds, out results, out diagnosticInfos)); }
/// <summary> /// Reads the attribute values from the server. /// </summary> /// <param name="valuesToWrite">The values to write.</param> /// <returns>The results.</returns> public int[] Write(WriteValueCollection valuesToWrite) { TraceState("Write", valuesToWrite.Count); // check for valid session. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } int masterError = ResultIds.E_FAIL; int[] errors = new int[valuesToWrite.Count]; if (session != null) { try { // write the values. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); // convert the response. for (int ii = 0; ii < results.Count; ii++) { errors[ii] = ComDaProxy.MapWriteStatusToErrorCode(valuesToWrite[ii].Value, results[ii]); } // return the results. return(errors); } catch (Exception e) { masterError = ComUtils.GetErrorCode(e, ResultIds.E_FAIL); } } // report any unexpected errors. for (int ii = 0; ii < errors.Length; ii++) { errors[ii] = masterError; } return(errors); }
/// <summary> /// Set monitoring mode of items. /// </summary> public async Task <List <ServiceResult> > SetMonitoringModeAsync( MonitoringMode monitoringMode, IList <MonitoredItem> monitoredItems, CancellationToken ct = default) { if (monitoredItems == null) { throw new ArgumentNullException(nameof(monitoredItems)); } VerifySubscriptionState(true); if (monitoredItems.Count == 0) { return(null); } // get list of items to update. UInt32Collection monitoredItemIds = new UInt32Collection(); foreach (MonitoredItem monitoredItem in monitoredItems) { monitoredItemIds.Add(monitoredItem.Status.Id); } var response = await m_session.SetMonitoringModeAsync( null, m_id, monitoringMode, monitoredItemIds, ct).ConfigureAwait(false); StatusCodeCollection results = response.Results; ClientBase.ValidateResponse(results, monitoredItemIds); ClientBase.ValidateDiagnosticInfos(response.DiagnosticInfos, monitoredItemIds); // update results. List <ServiceResult> errors = new List <ServiceResult>(); bool noErrors = UpdateMonitoringMode( monitoredItems, errors, results, response.DiagnosticInfos, response.ResponseHeader, monitoringMode); // raise state changed event. m_changeMask |= SubscriptionChangeMask.ItemsModified; ChangesCompleted(); // return null list if no errors occurred. if (noErrors) { return(null); } return(errors); }
public bool WriteNodes(List <string> NodeIds, List <string> Values) { var typeNodeIds = ReadNodes(NodeIds, Attributes.DataType); for (int i = 0; i < typeNodeIds.Count; i++) { if (!DataValue.IsGood(typeNodeIds[i])) { throw new ApplicationException("数据类型获取失败:" + NodeIds[i]); } } var builtinTypes = typeNodeIds.Select(typeNodeId => Opc.Ua.TypeInfo.GetBuiltInType(typeNodeId.Value as NodeId, m_session.TypeTree)).ToList(); var nodesToWrite = new WriteValueCollection(); for (int i = 0; i < NodeIds.Count; i++) { nodesToWrite.Add(new WriteValue() { NodeId = NodeIds[i], AttributeId = Attributes.Value, Value = new DataValue { Value = new Variant(Opc.Ua.TypeInfo.Cast(Values[i], builtinTypes[i])), StatusCode = StatusCodes.Good, ServerTimestamp = DateTime.MinValue, SourceTimestamp = DateTime.MinValue } }); } StatusCodeCollection results = new StatusCodeCollection(); DiagnosticInfoCollection diagnosticInfos = new DiagnosticInfoCollection(); m_session.Write( null, nodesToWrite, out results, out diagnosticInfos); //ClientBase.ValidateResponse(results, nodesToWrite); //ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); results.ForEach(x => { if (StatusCode.IsBad(x)) { throw new ServiceResultException(x); } }); return(true); }
/// <summary> /// Decodes a StatusCollection object and based on the status returns a Result object /// </summary> /// <param name="statusCodes"></param> /// <returns></returns> private Result GetResultFromStatus(StatusCodeCollection statusCodes) { if (statusCodes == null || statusCodes.Count == 0) { return(new Result(false, new Exception("Could not write tag value !"))); } bool isBad = false; isBad = statusCodes.Any(s => StatusCode.IsBad(s)); return(new Result(!isBad)); }
static async Task HandleSettingChanged(TwinCollection desiredProperties, object userContext) { string setting = "SetpointHeating"; if (desiredProperties.Contains(setting)) { BuildAcknowledgement(desiredProperties, setting); setpointHeating = (int)desiredProperties[setting]["value"]; greenMessage($"Heating Setpoint updated: {setpointHeating}"); // Write to OPC UA, Setpoint Temperature node try { WriteValue nodeToWrite = new WriteValue() { NodeId = SetpointHeatingNode, AttributeId = Attributes.Value, Value = new DataValue(setpointHeating) }; WriteValueCollection nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(nodeToWrite); // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; // Write to setpoint temperature node ResponseHeader responseHeader = session.Write(null, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check for error. if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // If no error, send the updated setpoint temperature to IoT Central. else if (StatusCode.IsGood(results[0])) { Console.WriteLine(session.ReadValue(SetpointHeatingNode).Value); await s_deviceClient.UpdateReportedPropertiesAsync(reportedProperties); // Send an informational event to IoT Central eventInfoText = "Setpoint Heating has been updated: " + setpointHeating.ToString() + " °C"; } } catch (Exception ex) { Console.WriteLine("Exception message: " + ex.Message); } } }
/// <summary> /// Creates a place holder in the lists for the results. /// </summary> public static void CreateSuccess( StatusCodeCollection results, DiagnosticInfoCollection diagnosticInfos, OperationContext context) { results.Add(StatusCodes.Good); if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos.Add(null); } }
public ResponseHeader Publish( RequestHeader requestHeader, SubscriptionAcknowledgementCollection subscriptionAcknowledgements, out uint subscriptionId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications, out NotificationMessage notificationMessage, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { return(m_session.Publish(requestHeader, subscriptionAcknowledgements, out subscriptionId, out availableSequenceNumbers, out moreNotifications, out notificationMessage, out results, out diagnosticInfos)); }
async static Task Run() { UserIdentity userIdentity = new UserIdentity(new AnonymousIdentityToken()); ApplicationInstance application = new ApplicationInstance { ApplicationName = "UA Core Complex Client", ApplicationType = ApplicationType.Client, ConfigSectionName = "Opc.Ua.ComplexClient" }; ApplicationConfiguration config = await application.LoadApplicationConfiguration("OpcConfig.xml", false).ConfigureAwait(false); var endpointURL = GetEnvVar("OPC_SERVER", "opc.tcp://localhost:62541/Quickstarts/ReferenceServer"); var selectedEndpoint = CoreClientUtils.SelectEndpoint(endpointURL, false && !true, 15000); var m_session = await CreateSession(config, selectedEndpoint, userIdentity).ConfigureAwait(false); WriteValueCollection nodesToWrite = new WriteValueCollection(); // Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32 WriteValue intWriteVal = new WriteValue(); intWriteVal.NodeId = new NodeId("ns=2;s=Tag_String"); intWriteVal.AttributeId = Attributes.Value; intWriteVal.Value = new DataValue(); intWriteVal.Value.Value = "Pierre-" + DateTime.Now.ToLongTimeString(); nodesToWrite.Add(intWriteVal); // Write the node attributes StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos; Console.WriteLine("Writing nodes..."); // Call Write Service m_session.Write(null, nodesToWrite, out results, out diagnosticInfos); // Validate the response ClientBase.ValidateResponse(results, nodesToWrite); // Display the results. Console.WriteLine("Write Results :"); foreach (StatusCode writeResult in results) { Console.WriteLine(" {0}", writeResult); } }
/// <summary> /// 注册服务(每个在本机启动的服务端都会主动调用此方法进行注册) /// </summary> /// <param name="requestHeader"></param> /// <param name="server"></param> /// <param name="discoveryConfiguration"></param> /// <param name="configurationResults"></param> /// <param name="diagnosticInfos"></param> /// <returns></returns> public virtual ResponseHeader RegisterServer2( RequestHeader requestHeader, RegisteredServer server, ExtensionObjectCollection discoveryConfiguration, out StatusCodeCollection configurationResults, out DiagnosticInfoCollection diagnosticInfos) { configurationResults = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. try { Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":服务注册:" + server.DiscoveryUrls.FirstOrDefault()); RegisteredServerTable model = _serverTable.Where(d => d.ServerUri == server.ServerUri).FirstOrDefault(); if (model != null) { model.LastRegistered = DateTime.Now; } else { model = new RegisteredServerTable() { DiscoveryUrls = server.DiscoveryUrls, GatewayServerUri = server.GatewayServerUri, IsOnline = server.IsOnline, LastRegistered = DateTime.Now, ProductUri = server.ProductUri, SemaphoreFilePath = server.SemaphoreFilePath, ServerNames = server.ServerNames, ServerType = server.ServerType, ServerUri = server.ServerUri }; _serverTable.Add(model); } configurationResults = new StatusCodeCollection() { StatusCodes.Good }; return(CreateResponse(requestHeader, StatusCodes.Good)); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("客户端调用RegisterServer2()注册服务时触发异常:" + ex.Message); Console.ResetColor(); } return(CreateResponse(requestHeader, StatusCodes.BadUnexpectedError)); }
/// <summary> /// Writes the values. /// </summary> private void WriteValues() { try { // Prepare call to ClientAPI. NodeIdCollection nodesToWrite = new NodeIdCollection(this.listView.Items.Count); DataValueCollection values = new DataValueCollection(this.listView.Items.Count); StatusCodeCollection results = null; int i = 0; foreach (ListViewItem item in this.listView.Items) { // Values to write. String sValue = (String)item.SubItems[0].Text; // Leave current value if write value is empty. if (sValue.Length == 0) { i++; continue; } Variant variant = new Variant(Convert.ChangeType(sValue, m_currentValues[i].Value.GetType())); DataValue value = new DataValue(variant); values.Add(value); // NodeIds. String sNodeId = item.SubItems[1].Text; NodeId nodeId = new NodeId(sNodeId); nodesToWrite.Add(nodeId); i++; } // Call to ClientAPI. m_Server.WriteValues( nodesToWrite, values, out results); // Update status label. toolStripStatusLabel.Text = "Writing values succeeded."; } catch (Exception e) { // Update status label. toolStripStatusLabel.Text = "An exception occured while writing values: " + e.Message; } }
public bool WriteValue(WriteValuePayload payload) { // credits: https://github.com/OPCFoundation/UA-.NETStandard/issues/316 if (!payload.IsValid) { return(false); } try { var nodeToWrite = new WriteValue(); var expandedNodeId = ExpandedNodeId.Parse(payload.ExtendedNodeId); nodeToWrite.NodeId = GetNodeIdFromExpandedNodeId(expandedNodeId); nodeToWrite.AttributeId = Attributes.Value; nodeToWrite.Value.WrappedValue = "actual data"; var nodesToWrite = new WriteValueCollection(); nodesToWrite.Add(nodeToWrite); // read the attribute StatusCodeCollection results = null; DiagnosticInfoCollection diagInfos = null; var responseHeader = OpcUaClientSession.Write( null, nodesToWrite, out results, out diagInfos ); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagInfos, nodesToWrite); // check for error if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagInfos, responseHeader.StringTable); } Trace($"Value written to {payload.ExtendedNodeId}"); } catch (Exception ex) { Trace($"An error occured when writing a value: {ex.Message}"); return(false); } return(true); }
/// <summary> /// Writes the value /// </summary> private Variant WriteValue(Session session, NodeId nodeId) { // cast the value to a string. object value = TypeInfo.Cast(ValueTB.Text, TypeInfo.Scalars.String, m_sourceType.BuiltInType); // build list of attributes to read. WriteValueCollection nodesToWrite = new WriteValueCollection(); WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = nodeId; nodeToWrite.AttributeId = Attributes.Value; // using the WrappedValue instead of the Value property because we know the TypeInfo. // this makes the assignment more efficient by avoiding reflection to determine type. nodeToWrite.Value.WrappedValue = new Variant(value, m_sourceType); nodesToWrite.Add(nodeToWrite); // override the diagnostic masks (other parameters are set to defaults). RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = session.Write( requestHeader, nodesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check status. if (StatusCode.IsBad(results[0])) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // return valid value. return(nodeToWrite.Value.WrappedValue); }
/// <summary> /// Handles a write request. /// </summary> public List <ServiceResult> Write(List <WriteRequest> requests) { if (m_session == null) { throw new ServiceResultException(StatusCodes.BadCommunicationError); } WriteValueCollection valuesToWrite = new WriteValueCollection(); for (int ii = 0; ii < requests.Count; ii++) { WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = ExpandedNodeId.ToNodeId(requests[ii].RemoteId, m_session.NamespaceUris); valueToWrite.AttributeId = requests[ii].WriteValue.AttributeId; valueToWrite.IndexRange = requests[ii].WriteValue.IndexRange; valueToWrite.Value = requests[ii].WriteValue.Value; valuesToWrite.Add(valueToWrite); } StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); Session.ValidateResponse(results, valuesToWrite); Session.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); List <ServiceResult> errors = new List <ServiceResult>(); for (int ii = 0; ii < requests.Count; ii++) { if (results[ii] != StatusCodes.Good) { errors.Add(new ServiceResult(results[ii], ii, diagnosticInfos, responseHeader.StringTable)); } else { errors.Add(null); } } return(errors); }
private void WriteValuePlus(String valueSign) { try { // 声明需要写入的数据 NodeIdCollection nodesToWrite = new NodeIdCollection(1); DataValueCollection values = new DataValueCollection(1); StatusCodeCollection results = null; Variant variant = new Variant(); DataValue value = new DataValue(); String sNodeId = ""; if (valueSign.Equals("X")) { String sValue = (MainWindow.myMotorPos.XValue + 1).ToString(); //variant = new Variant(MainWindow.myMotorPos.YValue + 1); variant = new Variant(Convert.ChangeType(sValue, m_currentXValue.Value.GetType())); value = new DataValue(variant); values.Add(value); sNodeId = "ns=2;s=Channel1.Device1.Tag1"; } else if (valueSign.Equals("Y")) { //variant = new Variant(MainWindow.myMotorPos.YValue + 1); String sValue = (MainWindow.myMotorPos.YValue + 1).ToString(); Type testType = m_currentYValue.Value.GetType(); variant = new Variant(Convert.ChangeType(sValue, m_currentYValue.Value.GetType())); value = new DataValue(variant); values.Add(value); sNodeId = "ns=2;s=Channel1.Device1.Tag2"; } NodeId nodeId = new NodeId(sNodeId); nodesToWrite.Add(nodeId); // 调用API方法 m_Server.WriteValues( nodesToWrite, values, out results); } catch (Exception ex) { MessageBox.Show("写入数据失败!错误原因:" + ex, "错误", MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnWrite_Click(object sender, EventArgs e) { string nodeID = txtNodeID.Text.Trim(); string writevalue = txtWriteValue.Text.Trim(); if (string.IsNullOrEmpty(nodeID)) { MessageBox.Show("请输入NodeID"); return; } if (string.IsNullOrEmpty(writevalue)) { MessageBox.Show("请输入写入的值"); return; } NodeIdCollection nic = new NodeIdCollection(); NodeId nodeid = new NodeId(nodeID); nic.Add(nodeid); DataValueCollection valueC; server.ReadValues( nic, out valueC); Variant variant = new Variant(Convert.ChangeType(writevalue, valueC[0].Value.GetType())); DataValueCollection values = new DataValueCollection(); DataValue value = new DataValue(variant); values.Add(value); StatusCodeCollection results = null; server.WriteValues( nic, values, out results); txtReadValue.Text = writevalue; txtResult.Text = "write success"; }
/// <summary> /// Fills in the diagnostic information after an error. /// </summary> public static bool CreateError( uint code, StatusCodeCollection results, DiagnosticInfoCollection diagnosticInfos, OperationContext context) { ServiceResult error = new ServiceResult(code); results.Add(error.Code); if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos.Add(new DiagnosticInfo(error, context.DiagnosticsMask, false, context.StringTable)); return true; } return false; }
private void ChangeLogFileBTN_Click(object sender, EventArgs e) { if (m_session == null) { return; } try { // want to get error text for this call. m_session.ReturnDiagnostics = DiagnosticsMasks.All; WriteValue value = new WriteValue(); value.NodeId = m_logFileNodeId; value.AttributeId = Attributes.Value; value.Value.Value = LogFilePathTB.Text; WriteValueCollection valuesToWrite = new WriteValueCollection(); valuesToWrite.Add(value); StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = m_session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } finally { m_session.ReturnDiagnostics = DiagnosticsMasks.None; } }
public void WriteTag(Tag tag, object value) { //non è ancora stata effettuata la lettura della tag if (tag.Type == null) { return; throw new NotImplementedException(); } try { WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = tag.NodeId; valueToWrite.AttributeId = 13; valueToWrite.Value.Value = ChangeType(tag, value); valueToWrite.Value.StatusCode = StatusCodes.Good; valueToWrite.Value.ServerTimestamp = DateTime.MinValue; valueToWrite.Value.SourceTimestamp = DateTime.MinValue; WriteValueCollection valuesToWrite = new WriteValueCollection(); valuesToWrite.Add(valueToWrite); // write current value. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Write( null, valuesToWrite, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, valuesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToWrite); if (StatusCode.IsBad(results[0])) { throw new ServiceResultException(results[0]); } } catch (Exception exception) { throw new NotImplementedException(); } }
/// <summary> /// Deletes the monitored items in a subscription. /// </summary> private void DeleteMonitoredItems( OperationContext context, UInt32Collection monitoredItemIds, bool doNotCheckSession, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (monitoredItemIds == null) throw new ArgumentNullException("monitoredItemIds"); int count = monitoredItemIds.Count; bool diagnosticsExist = false; results = new StatusCodeCollection(count); diagnosticInfos = null; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos = new DiagnosticInfoCollection(count); } // build list of items to modify. List<IMonitoredItem> monitoredItems = new List<IMonitoredItem>(count); List<ServiceResult> errors = new List<ServiceResult>(count); double[] originalSamplingIntervals = new double[count]; MonitoringMode[] originalMonitoringModes = new MonitoringMode[count]; bool validItems = false; lock (m_lock) { // check session. if (!doNotCheckSession) { VerifySession(context); } // clear lifetime counter. ResetLifetimeCount(); for (int ii = 0; ii < count; ii++) { LinkedListNode<IMonitoredItem> node = null; if (!m_monitoredItems.TryGetValue(monitoredItemIds[ii], out node)) { monitoredItems.Add(null); errors.Add(StatusCodes.BadMonitoredItemIdInvalid); // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]); diagnosticsExist = true; diagnosticInfos.Add(diagnosticInfo); } continue; } IMonitoredItem monitoredItem = node.Value; monitoredItems.Add(monitoredItem); // remove the item from the internal lists. m_monitoredItems.Remove(monitoredItemIds[ii]); m_itemsToTrigger.Remove(monitoredItemIds[ii]); //remove the links towards the deleted monitored item List<ITriggeredMonitoredItem> triggeredItems = null; foreach (KeyValuePair<uint, List<ITriggeredMonitoredItem>> item in m_itemsToTrigger) { triggeredItems = item.Value; for (int jj = 0; jj < triggeredItems.Count; jj++) { if (triggeredItems[jj].Id == monitoredItemIds[ii]) { triggeredItems.RemoveAt(jj); break; } } } if (node.List != null) { node.List.Remove(node); } originalSamplingIntervals[ii] = monitoredItem.SamplingInterval; originalMonitoringModes[ii] = monitoredItem.MonitoringMode; errors.Add(null); validItems = true; // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos.Add(null); } } } // update items. if (validItems) { m_server.NodeManager.DeleteMonitoredItems( context, m_id, monitoredItems, errors); } lock (m_lock) { // update diagnostics. for (int ii = 0; ii < errors.Count; ii++) { ServiceResult error = errors[ii]; if (error == null) { results.Add(StatusCodes.Good); } else { results.Add(error.StatusCode); } // update diagnostics. if (ServiceResult.IsGood(error)) { RemoveItemToSamplingInterval(originalSamplingIntervals[ii], originalMonitoringModes[ii]); } if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { if (error != null && error.Code != StatusCodes.Good) { diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, error); diagnosticsExist = true; } } } // clear diagnostics if not required. if (!diagnosticsExist && diagnosticInfos != null) { diagnosticInfos.Clear(); } // update diagnostics. lock (m_diagnostics) { m_diagnostics.MonitoredItemCount = 0; m_diagnostics.DisabledMonitoredItemCount = 0; } // TraceState("ITEMS DELETED"); } }
/// <summary> /// Updates the triggers for the monitored item. /// </summary> public void SetTriggering( OperationContext context, uint triggeringItemId, UInt32Collection linksToAdd, UInt32Collection linksToRemove, out StatusCodeCollection addResults, out DiagnosticInfoCollection addDiagnosticInfos, out StatusCodeCollection removeResults, out DiagnosticInfoCollection removeDiagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (linksToAdd == null) throw new ArgumentNullException("linksToAdd"); if (linksToRemove == null) throw new ArgumentNullException("linksToRemove"); // allocate results. bool diagnosticsExist = false; addResults = new StatusCodeCollection(); addDiagnosticInfos = null; removeResults = new StatusCodeCollection(); removeDiagnosticInfos = null; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { addDiagnosticInfos = new DiagnosticInfoCollection(); removeDiagnosticInfos = new DiagnosticInfoCollection(); } // build list of items to modify. lock (m_lock) { // check session. VerifySession(context); // clear lifetime counter. ResetLifetimeCount(); // look up triggering item. LinkedListNode<IMonitoredItem> triggerNode = null; if (!m_monitoredItems.TryGetValue(triggeringItemId, out triggerNode)) { throw new ServiceResultException(StatusCodes.BadMonitoredItemIdInvalid); } // lookup existing list. List<ITriggeredMonitoredItem> triggeredItems = null; if (!m_itemsToTrigger.TryGetValue(triggeringItemId, out triggeredItems)) { m_itemsToTrigger[triggeringItemId] = triggeredItems = new List<ITriggeredMonitoredItem>(); } // remove old links. for (int ii = 0; ii < linksToRemove.Count; ii++) { removeResults.Add(StatusCodes.Good); bool found = false; for (int jj = 0; jj < triggeredItems.Count; jj++) { if (triggeredItems[jj].Id == linksToRemove[ii]) { found = true; triggeredItems.RemoveAt(jj); break; } } if (!found) { removeResults[ii] = StatusCodes.BadMonitoredItemIdInvalid; // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, removeResults[ii]); diagnosticsExist = true; removeDiagnosticInfos.Add(diagnosticInfo); } continue; } // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { removeDiagnosticInfos.Add(null); } } // add new links. for (int ii = 0; ii < linksToAdd.Count; ii++) { addResults.Add(StatusCodes.Good); LinkedListNode<IMonitoredItem> node = null; if (!m_monitoredItems.TryGetValue(linksToAdd[ii], out node)) { addResults[ii] = StatusCodes.BadMonitoredItemIdInvalid; // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, addResults[ii]); diagnosticsExist = true; addDiagnosticInfos.Add(diagnosticInfo); } continue; } // check if triggering interface is supported. ITriggeredMonitoredItem triggeredItem = node.Value as ITriggeredMonitoredItem; if (triggeredItem == null) { addResults[ii] = StatusCodes.BadNotSupported; // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, addResults[ii]); diagnosticsExist = true; addDiagnosticInfos.Add(diagnosticInfo); } continue; } // add value if not already in list. bool found = false; for (int jj = 0; jj < triggeredItems.Count; jj++) { if (triggeredItems[jj].Id == triggeredItem.Id) { found = true; break; } } if (!found) { triggeredItems.Add(triggeredItem); } // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { addDiagnosticInfos.Add(null); } } // remove an empty list. if (triggeredItems.Count == 0) { m_itemsToTrigger.Remove(triggeringItemId); } // clear diagnostics if not required. if (!diagnosticsExist) { if (addDiagnosticInfos != null) addDiagnosticInfos.Clear(); if (removeDiagnosticInfos != null) removeDiagnosticInfos.Clear(); } } }
/// <summary> /// Invokes the Publish service. /// </summary> public virtual ResponseHeader Publish( RequestHeader requestHeader, SubscriptionAcknowledgementCollection subscriptionAcknowledgements, out uint subscriptionId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications, out NotificationMessage notificationMessage, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { PublishRequest request = new PublishRequest(); PublishResponse response = null; request.RequestHeader = requestHeader; request.SubscriptionAcknowledgements = subscriptionAcknowledgements; UpdateRequestHeader(request, requestHeader == null, "Publish"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (PublishResponse)genericResponse; } else { PublishResponseMessage responseMessage = InnerChannel.Publish(new PublishMessage(request)); if (responseMessage == null || responseMessage.PublishResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.PublishResponse; ValidateResponse(response.ResponseHeader); } subscriptionId = response.SubscriptionId; availableSequenceNumbers = response.AvailableSequenceNumbers; moreNotifications = response.MoreNotifications; notificationMessage = response.NotificationMessage; results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "Publish"); } return response.ResponseHeader; }
/// <summary> /// Invokes the DeleteReferences service. /// </summary> public virtual ResponseHeader DeleteReferences( RequestHeader requestHeader, DeleteReferencesItemCollection referencesToDelete, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the RegisterServer2 service. /// </summary> public virtual ResponseHeader RegisterServer2( RequestHeader requestHeader, RegisteredServer server, ExtensionObjectCollection discoveryConfiguration, out StatusCodeCollection configurationResults, out DiagnosticInfoCollection diagnosticInfos) { configurationResults = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the Publish service. /// </summary> public virtual ResponseHeader Publish( RequestHeader requestHeader, SubscriptionAcknowledgementCollection subscriptionAcknowledgements, out uint subscriptionId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications, out NotificationMessage notificationMessage, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { subscriptionId = 0; availableSequenceNumbers = null; moreNotifications = false; notificationMessage = null; results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the Publish service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="subscriptionAcknowledgements">The list of acknowledgements for one or more Subscriptions.</param> /// <param name="subscriptionId">The subscription identifier.</param> /// <param name="availableSequenceNumbers">The available sequence numbers.</param> /// <param name="moreNotifications">If set to <c>true</c> the number of Notifications that were ready to be sent could not be sent in a single response.</param> /// <param name="notificationMessage">The NotificationMessage that contains the list of Notifications.</param> /// <param name="results">The list of results for the acknowledgements.</param> /// <param name="diagnosticInfos">The diagnostic information for the results.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader Publish( RequestHeader requestHeader, SubscriptionAcknowledgementCollection subscriptionAcknowledgements, out uint subscriptionId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications, out NotificationMessage notificationMessage, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { OperationContext context = ValidateRequest(requestHeader, RequestType.Publish); try { /* // check if there is an odd delay. if (DateTime.UtcNow > requestHeader.Timestamp.AddMilliseconds(100)) { Utils.Trace( "WARNING. Unexpected delay receiving Publish request. Time={0:hh:mm:ss.fff}, ReceiveTime={1:hh:mm:ss.fff}", DateTime.UtcNow, requestHeader.Timestamp); } */ Utils.Trace("PUBLISH #{0} RECIEVED. TIME={1:hh:hh:ss.fff}", requestHeader.RequestHandle, requestHeader.Timestamp); notificationMessage = ServerInternal.SubscriptionManager.Publish( context, subscriptionAcknowledgements, null, out subscriptionId, out availableSequenceNumbers, out moreNotifications, out results, out diagnosticInfos); /* if (notificationMessage != null) { Utils.Trace( "PublishResponse: SubId={0} SeqNo={1}, PublishTime={2:mm:ss.fff}, Time={3:mm:ss.fff}", subscriptionId, notificationMessage.SequenceNumber, notificationMessage.PublishTime, DateTime.UtcNow); } */ return CreateResponse(requestHeader, context.StringTable); } catch (ServiceResultException e) { lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException(context, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Invokes the Write service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="nodesToWrite">The list of Nodes, Attributes, and values to write.</param> /// <param name="results">The list of write result status codes for each write operation.</param> /// <param name="diagnosticInfos">The diagnostic information for the results.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader Write( RequestHeader requestHeader, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { OperationContext context = ValidateRequest(requestHeader, RequestType.Write); try { if (nodesToWrite == null || nodesToWrite.Count == 0) { throw new ServiceResultException(StatusCodes.BadNothingToDo); } m_serverInternal.NodeManager.Write( context, nodesToWrite, out results, out diagnosticInfos); return CreateResponse(requestHeader, context.StringTable); } catch (ServiceResultException e) { lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException(context, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Finishes an asynchronous invocation of the DeleteNodes service. /// </summary> public ResponseHeader EndDeleteNodes( IAsyncResult result, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { DeleteNodesResponse response = null; try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.EndSendRequest(result); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (DeleteNodesResponse)genericResponse; } else { DeleteNodesResponseMessage responseMessage = InnerChannel.EndDeleteNodes(result); if (responseMessage == null || responseMessage.DeleteNodesResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.DeleteNodesResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(null, response, "DeleteNodes"); } return response.ResponseHeader; }
/// <summary> /// Reads an StatusCode array from the stream. /// </summary> public StatusCodeCollection ReadStatusCodeArray(string fieldName) { int length = ReadArrayLength(); if (length == -1) { return null; } StatusCodeCollection values = new StatusCodeCollection(length); for (int ii = 0; ii < length; ii++) { values.Add(ReadStatusCode(null)); } return values; }
/// <summary> /// Creates a collection of status codes and diagnostics from a set of errors. /// </summary> public static StatusCodeCollection CreateStatusCodeCollection( OperationContext context, IList<ServiceResult> errors, out DiagnosticInfoCollection diagnosticInfos) { diagnosticInfos = null; bool noErrors = true; StatusCodeCollection results = new StatusCodeCollection(errors.Count); foreach (ServiceResult error in errors) { if (ServiceResult.IsBad(error)) { results.Add(error.Code); noErrors = false; } else { results.Add(StatusCodes.Good); } } // only generate diagnostics if errors exist. if (noErrors) { diagnosticInfos = CreateDiagnosticInfoCollection(context, errors); } return results; }
/// <summary> /// Writes a set of values. /// </summary> public virtual void Write( OperationContext context, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (nodesToWrite == null) throw new ArgumentNullException("nodesToWrite"); int count = nodesToWrite.Count; bool diagnosticsExist = false; results = new StatusCodeCollection(count); diagnosticInfos = new DiagnosticInfoCollection(count); // add placeholder for each result. bool validItems = false; for (int ii = 0; ii < count; ii++) { StatusCode result = StatusCodes.Good; DiagnosticInfo diagnosticInfo = null; // pre-validate and pre-parse parameter. ServiceResult error = WriteValue.Validate(nodesToWrite[ii]); // return error status. if (ServiceResult.IsBad(error)) { nodesToWrite[ii].Processed = true; result = error.Code; // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, error); diagnosticsExist = true; } } // found at least one valid item. else { nodesToWrite[ii].Processed = false; validItems = true; } results.Add(result); diagnosticInfos.Add(diagnosticInfo); } // call each node manager. if (validItems) { List<ServiceResult> errors = new List<ServiceResult>(count); errors.AddRange(new ServiceResult[count]); foreach (INodeManager nodeManager in m_nodeManagers) { nodeManager.Write( context, nodesToWrite, errors); } for (int ii = 0; ii < nodesToWrite.Count; ii++) { if (!nodesToWrite[ii].Processed) { errors[ii] = StatusCodes.BadNodeIdUnknown; } if (errors[ii] != null && errors[ii].Code != StatusCodes.Good) { results[ii] = errors[ii].Code; // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]); diagnosticsExist = true; } } ServerUtils.ReportWriteValue(nodesToWrite[ii].NodeId, nodesToWrite[ii].Value, results[ii]); } } // clear the diagnostics array if no diagnostics requested or no errors occurred. UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos); }
/// <summary> /// Invokes the SetMonitoringMode service. /// </summary> public virtual ResponseHeader SetMonitoringMode( RequestHeader requestHeader, uint subscriptionId, MonitoringMode monitoringMode, UInt32Collection monitoredItemIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the SetTriggering service. /// </summary> public virtual ResponseHeader SetTriggering( RequestHeader requestHeader, uint subscriptionId, uint triggeringItemId, UInt32Collection linksToAdd, UInt32Collection linksToRemove, out StatusCodeCollection addResults, out DiagnosticInfoCollection addDiagnosticInfos, out StatusCodeCollection removeResults, out DiagnosticInfoCollection removeDiagnosticInfos) { addResults = null; addDiagnosticInfos = null; removeResults = null; removeDiagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the SetTriggering service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="subscriptionId">The subscription id.</param> /// <param name="triggeringItemId">The id for the MonitoredItem used as the triggering item.</param> /// <param name="linksToAdd">The list of ids of the items to report that are to be added as triggering links.</param> /// <param name="linksToRemove">The list of ids of the items to report for the triggering links to be deleted.</param> /// <param name="addResults">The list of StatusCodes for the items to add.</param> /// <param name="addDiagnosticInfos">The list of diagnostic information for the links to add.</param> /// <param name="removeResults">The list of StatusCodes for the items to delete.</param> /// <param name="removeDiagnosticInfos">The list of diagnostic information for the links to delete.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader SetTriggering( RequestHeader requestHeader, uint subscriptionId, uint triggeringItemId, UInt32Collection linksToAdd, UInt32Collection linksToRemove, out StatusCodeCollection addResults, out DiagnosticInfoCollection addDiagnosticInfos, out StatusCodeCollection removeResults, out DiagnosticInfoCollection removeDiagnosticInfos) { addResults = null; addDiagnosticInfos = null; removeResults = null; removeDiagnosticInfos = null; OperationContext context = ValidateRequest(requestHeader, RequestType.SetTriggering); try { if ((linksToAdd == null || linksToAdd.Count == 0) && (linksToRemove == null || linksToRemove.Count == 0)) { throw new ServiceResultException(StatusCodes.BadNothingToDo); } ServerInternal.SubscriptionManager.SetTriggering( context, subscriptionId, triggeringItemId, linksToAdd, linksToRemove, out addResults, out addDiagnosticInfos, out removeResults, out removeDiagnosticInfos); return CreateResponse(requestHeader, context.StringTable); } catch (ServiceResultException e) { lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException(context, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Invokes the DeleteSubscriptions service. /// </summary> public virtual ResponseHeader DeleteSubscriptions( RequestHeader requestHeader, UInt32Collection subscriptionIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the SetMonitoringMode service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="subscriptionId">The subscription id.</param> /// <param name="monitoringMode">The monitoring mode to be set for the MonitoredItems.</param> /// <param name="monitoredItemIds">The list of MonitoredItems to modify.</param> /// <param name="results">The list of results for the MonitoredItems to modify.</param> /// <param name="diagnosticInfos">The diagnostic information for the results.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader SetMonitoringMode( RequestHeader requestHeader, uint subscriptionId, MonitoringMode monitoringMode, UInt32Collection monitoredItemIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { OperationContext context = ValidateRequest(requestHeader, RequestType.SetMonitoringMode); try { if (monitoredItemIds == null || monitoredItemIds.Count == 0) { throw new ServiceResultException(StatusCodes.BadNothingToDo); } ServerInternal.SubscriptionManager.SetMonitoringMode( context, subscriptionId, monitoringMode, monitoredItemIds, out results, out diagnosticInfos); return CreateResponse(requestHeader, context.StringTable); } catch (ServiceResultException e) { lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException(context, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Invokes the ActivateSession service. /// </summary> public virtual ResponseHeader ActivateSession( RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, out byte[] serverNonce, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { serverNonce = null; results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the ActivateSession service. /// </summary> /// <param name="requestHeader">The request header.</param> /// <param name="clientSignature">The client signature.</param> /// <param name="clientSoftwareCertificates">The client software certificates.</param> /// <param name="localeIds">The locale ids.</param> /// <param name="userIdentityToken">The user identity token.</param> /// <param name="userTokenSignature">The user token signature.</param> /// <param name="serverNonce">The server nonce.</param> /// <param name="results">The results.</param> /// <param name="diagnosticInfos">The diagnostic infos.</param> /// <returns> /// Returns a <see cref="ResponseHeader"/> object /// </returns> public override ResponseHeader ActivateSession( RequestHeader requestHeader, SignatureData clientSignature, SignedSoftwareCertificateCollection clientSoftwareCertificates, StringCollection localeIds, ExtensionObject userIdentityToken, SignatureData userTokenSignature, out byte[] serverNonce, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { serverNonce = null; results = null; diagnosticInfos = null; OperationContext context = ValidateRequest(requestHeader, RequestType.ActivateSession); try { // validate client's software certificates. List<SoftwareCertificate> softwareCertificates = new List<SoftwareCertificate>(); if (context.SecurityPolicyUri != SecurityPolicies.None) { bool diagnosticsExist = false; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos = new DiagnosticInfoCollection(); } results = new StatusCodeCollection(); diagnosticInfos = new DiagnosticInfoCollection(); foreach (SignedSoftwareCertificate signedCertificate in clientSoftwareCertificates) { SoftwareCertificate softwareCertificate = null; ServiceResult result = SoftwareCertificate.Validate( new CertificateValidator(), signedCertificate.CertificateData, out softwareCertificate); if (ServiceResult.IsBad(result)) { results.Add(result.Code); // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(ServerInternal, context, result); diagnosticInfos.Add(diagnosticInfo); diagnosticsExist = true; } } else { softwareCertificates.Add(softwareCertificate); results.Add(StatusCodes.Good); // add diagnostics if requested. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos.Add(null); } } } if (!diagnosticsExist && diagnosticInfos != null) { diagnosticInfos.Clear(); } } // check if certificates meet the server's requirements. ValidateSoftwareCertificates(softwareCertificates); // activate the session. bool identityChanged = ServerInternal.SessionManager.ActivateSession( context, requestHeader.AuthenticationToken, clientSignature, softwareCertificates, userIdentityToken, userTokenSignature, localeIds, out serverNonce); if (identityChanged) { // TBD - call Node Manager and Subscription Manager. } Utils.Trace("Server - SESSION ACTIVATED."); return CreateResponse(requestHeader, StatusCodes.Good); } catch (ServiceResultException e) { Utils.Trace("Server - SESSION ACTIVATE failed. {0}", e.Message); lock (ServerInternal.DiagnosticsLock) { ServerInternal.ServerDiagnostics.RejectedRequestsCount++; if (IsSecurityError(e.StatusCode)) { ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++; } } throw TranslateException((DiagnosticsMasks)requestHeader.ReturnDiagnostics, localeIds, e); } finally { OnRequestComplete(context); } }
/// <summary> /// Invokes the Write service. /// </summary> public virtual ResponseHeader Write( RequestHeader requestHeader, WriteValueCollection nodesToWrite, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { results = null; diagnosticInfos = null; ValidateRequest(requestHeader); // Insert implementation. return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported); }
/// <summary> /// Invokes the DeleteNodes service. /// </summary> public virtual ResponseHeader DeleteNodes( RequestHeader requestHeader, DeleteNodesItemCollection nodesToDelete, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { DeleteNodesRequest request = new DeleteNodesRequest(); DeleteNodesResponse response = null; request.RequestHeader = requestHeader; request.NodesToDelete = nodesToDelete; UpdateRequestHeader(request, requestHeader == null, "DeleteNodes"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (DeleteNodesResponse)genericResponse; } else { DeleteNodesResponseMessage responseMessage = InnerChannel.DeleteNodes(new DeleteNodesMessage(request)); if (responseMessage == null || responseMessage.DeleteNodesResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.DeleteNodesResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "DeleteNodes"); } return response.ResponseHeader; }
/// <summary> /// Processes acknowledgements for previously published messages. /// </summary> public void Acknowledge( OperationContext context, SubscriptionAcknowledgementCollection subscriptionAcknowledgements, out StatusCodeCollection acknowledgeResults, out DiagnosticInfoCollection acknowledgeDiagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (subscriptionAcknowledgements == null) throw new ArgumentNullException("subscriptionAcknowledgements"); lock (m_lock) { bool diagnosticsExist = false; acknowledgeResults = new StatusCodeCollection(subscriptionAcknowledgements.Count); acknowledgeDiagnosticInfos = new DiagnosticInfoCollection(subscriptionAcknowledgements.Count); for (int ii = 0; ii < subscriptionAcknowledgements.Count; ii++) { SubscriptionAcknowledgement acknowledgement = subscriptionAcknowledgements[ii]; bool found = false; for (int jj = 0; jj < m_queuedSubscriptions.Count; jj++) { QueuedSubscription subscription = m_queuedSubscriptions[jj]; if (subscription.Subscription.Id == acknowledgement.SubscriptionId) { ServiceResult result = subscription.Subscription.Acknowledge(context, acknowledgement.SequenceNumber); if (ServiceResult.IsGood(result)) { acknowledgeResults.Add(StatusCodes.Good); if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { acknowledgeDiagnosticInfos.Add(null); } } else { acknowledgeResults.Add(result.Code); if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, result); acknowledgeDiagnosticInfos.Add(diagnosticInfo); diagnosticsExist = true; } } found = true; break; } } if (!found) { ServiceResult result = new ServiceResult(StatusCodes.BadSubscriptionIdInvalid); acknowledgeResults.Add(result.Code); if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, result); acknowledgeDiagnosticInfos.Add(diagnosticInfo); diagnosticsExist = true; } } } if (!diagnosticsExist) { acknowledgeDiagnosticInfos.Clear(); } } }
/// <summary> /// Reads an StatusCode array from the stream. /// </summary> public StatusCodeCollection ReadStatusCodeArray(string fieldName) { bool isNil = false; StatusCodeCollection values = new StatusCodeCollection(); if (BeginField(fieldName, true, out isNil)) { PushNamespace(Namespaces.OpcUaXsd); while (MoveToElement("StatusCode")) { values.Add(ReadStatusCode("StatusCode")); } // check the length. if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count) { throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded); } PopNamespace(); EndField(fieldName); return values; } if (isNil) { return null; } return values; }
/// <summary> /// Invokes the SetPublishingMode service. /// </summary> public virtual ResponseHeader SetPublishingMode( RequestHeader requestHeader, bool publishingEnabled, UInt32Collection subscriptionIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { SetPublishingModeRequest request = new SetPublishingModeRequest(); SetPublishingModeResponse response = null; request.RequestHeader = requestHeader; request.PublishingEnabled = publishingEnabled; request.SubscriptionIds = subscriptionIds; UpdateRequestHeader(request, requestHeader == null, "SetPublishingMode"); try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.SendRequest(request); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (SetPublishingModeResponse)genericResponse; } else { SetPublishingModeResponseMessage responseMessage = InnerChannel.SetPublishingMode(new SetPublishingModeMessage(request)); if (responseMessage == null || responseMessage.SetPublishingModeResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.SetPublishingModeResponse; ValidateResponse(response.ResponseHeader); } results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(request, response, "SetPublishingMode"); } return response.ResponseHeader; }
/// <summary> /// Finishes an asynchronous invocation of the Publish service. /// </summary> public ResponseHeader EndPublish( IAsyncResult result, out uint subscriptionId, out UInt32Collection availableSequenceNumbers, out bool moreNotifications, out NotificationMessage notificationMessage, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { PublishResponse response = null; try { if (UseTransportChannel) { IServiceResponse genericResponse = TransportChannel.EndSendRequest(result); if (genericResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } ValidateResponse(genericResponse.ResponseHeader); response = (PublishResponse)genericResponse; } else { PublishResponseMessage responseMessage = InnerChannel.EndPublish(result); if (responseMessage == null || responseMessage.PublishResponse == null) { throw new ServiceResultException(StatusCodes.BadUnknownResponse); } response = responseMessage.PublishResponse; ValidateResponse(response.ResponseHeader); } subscriptionId = response.SubscriptionId; availableSequenceNumbers = response.AvailableSequenceNumbers; moreNotifications = response.MoreNotifications; notificationMessage = response.NotificationMessage; results = response.Results; diagnosticInfos = response.DiagnosticInfos; } finally { RequestCompleted(null, response, "Publish"); } return response.ResponseHeader; }
/// <summary> /// Deletes the monitored items in a subscription. /// </summary> public void DeleteMonitoredItems( OperationContext context, UInt32Collection monitoredItemIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { DeleteMonitoredItems(context, monitoredItemIds, false, out results, out diagnosticInfos); }
/// <summary> /// Verifies the result of a publish /// </summary> private bool VerifyPublishResponse( ResponseHeader responseHeader, Subscription subscription, UInt32Collection availableSequenceNumbers, bool moreNotifications, NotificationMessage notificationMessage, StatusCodeCollection results, DiagnosticInfoCollection diagnosticInfos) { /* Utils.Trace( "PublishReceived: SubId={0} SeqNo={1}, PublishTime={2:mm:ss.fff}, Time={3:mm:ss.fff}", subscription.SubscriptionId, notificationMessage.SequenceNumber, notificationMessage.PublishTime, DateTime.UtcNow); */ // check if there is an odd delay. if (responseHeader.Timestamp > notificationMessage.PublishTime.AddMilliseconds(100)) { Log( "WARNING. Unexpected delay between PublishTime and ResponseTime. SeqNo={0}, PublishTime={1:hh:mm:ss.fff}, ResponseTime={2:hh:mm:ss.fff}", notificationMessage.SequenceNumber, notificationMessage.PublishTime, responseHeader.Timestamp); } // save results. subscription.AvailableSequenceNumbers = availableSequenceNumbers; if (notificationMessage.NotificationData.Count == 0) { // keep alives do not increment the sequence number. if (subscription.NextExpectedSequenceNumber != notificationMessage.SequenceNumber) { Log( "Incorrect sequence number for keep alive. SubscriptionId = {0}, Actual = {1}, Expected = {2}", subscription.SubscriptionId, notificationMessage.SequenceNumber, subscription.NextExpectedSequenceNumber); subscription.Failed = true; return false; } // save the message. DateTime timestamp = responseHeader.Timestamp; DateTime start = subscription.States[subscription.States.Count - 1].Start; // check if this is an old request being processed late. if (start > timestamp && subscription.States.Count > 1) { subscription.States[subscription.States.Count - 2].KeepAlives.Add(timestamp); } else { subscription.States[subscription.States.Count - 1].KeepAlives.Add(timestamp); } } else { // check for replays. if (subscription.NextExpectedSequenceNumber > notificationMessage.SequenceNumber) { // check for out of order responses. bool found = false; for (int ii = 0; ii < subscription.MissingSequenceNumbers.Count; ii++) { if (subscription.MissingSequenceNumbers[ii] == notificationMessage.SequenceNumber) { subscription.MissingSequenceNumbers.RemoveAt(ii); found = true; break; } } // oops - duplicate. if (!found) { Log( "Duplicate sequence number for message. SubscriptionId = {0}, Actual = {1}, Expected = {2}", subscription.SubscriptionId, notificationMessage.SequenceNumber, subscription.NextExpectedSequenceNumber); subscription.Failed = true; return false; } } // increment message counter. if (notificationMessage.SequenceNumber >= subscription.NextExpectedSequenceNumber) { for (uint ii = subscription.NextExpectedSequenceNumber; ii < notificationMessage.SequenceNumber; ii++) { if (!subscription.MissingSequenceNumbers.Contains(ii)) { subscription.MissingSequenceNumbers.Add(ii); } } subscription.NextExpectedSequenceNumber = notificationMessage.SequenceNumber+1; } // save the largest received message number (gap exist because of client side threading issues). if (subscription.LastReceivedSequenceNumber < notificationMessage.SequenceNumber) { subscription.LastReceivedSequenceNumber = notificationMessage.SequenceNumber; } // save the message. DateTime timestamp = responseHeader.Timestamp; DateTime start = subscription.States[subscription.States.Count-1].Start; // check if this is an old request being processed late. if (start > timestamp && subscription.States.Count > 1) { subscription.States[subscription.States.Count - 2].KeepAlives.Add(timestamp); } else { subscription.States[subscription.States.Count - 1].KeepAlives.Add(timestamp); } subscription.NotificationMessages.Add(notificationMessage); subscription.ReceiveTimes.Add(responseHeader.Timestamp); // change to keep alive mode. if (subscription.StaticData) { PublishingState state = new PublishingState(); state.KeepAliveCount = subscription.KeepAliveCount; state.PublishingInterval = subscription.PublishingInterval; state.Start = timestamp; state.KeepAliveMode = true; subscription.States[subscription.States.Count-1].End = state.Start; subscription.States.Add(state); } // save the acknowlegements. SaveAcknowledgement(subscription.SubscriptionId, notificationMessage.SequenceNumber); } return true; }
/// <summary> /// Changes the monitoring mode for a set of items. /// </summary> public void SetMonitoringMode( OperationContext context, MonitoringMode monitoringMode, UInt32Collection monitoredItemIds, out StatusCodeCollection results, out DiagnosticInfoCollection diagnosticInfos) { if (context == null) throw new ArgumentNullException("context"); if (monitoredItemIds == null) throw new ArgumentNullException("monitoredItemIds"); int count = monitoredItemIds.Count; bool diagnosticsExist = false; results = new StatusCodeCollection(count); diagnosticInfos = null; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos = new DiagnosticInfoCollection(count); } // build list of items to modify. List<IMonitoredItem> monitoredItems = new List<IMonitoredItem>(count); List<ServiceResult> errors = new List<ServiceResult>(count); MonitoringMode[] originalMonitoringModes = new MonitoringMode[count]; bool validItems = false; lock (m_lock) { // check session. VerifySession(context); // clear lifetime counter. ResetLifetimeCount(); for (int ii = 0; ii < count; ii++) { LinkedListNode<IMonitoredItem> node = null; if (!m_monitoredItems.TryGetValue(monitoredItemIds[ii], out node)) { monitoredItems.Add(null); errors.Add(StatusCodes.BadMonitoredItemIdInvalid); // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { DiagnosticInfo diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]); diagnosticsExist = true; diagnosticInfos.Add(diagnosticInfo); } continue; } IMonitoredItem monitoredItem = node.Value; monitoredItems.Add(monitoredItem); originalMonitoringModes[ii] = monitoredItem.MonitoringMode; errors.Add(null); validItems = true; // update diagnostics. if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos.Add(null); } } } // update items. if (validItems) { m_server.NodeManager.SetMonitoringMode( context, monitoringMode, monitoredItems, errors); } lock (m_lock) { // update diagnostics. for (int ii = 0; ii < errors.Count; ii++) { ServiceResult error = errors[ii]; if (error == null) { results.Add(StatusCodes.Good); } else { results.Add(error.StatusCode); } // update diagnostics. if (ServiceResult.IsGood(error)) { ModifyItemMonitoringMode(monitoredItems[ii].SamplingInterval, originalMonitoringModes[ii], monitoringMode); } if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { if (error != null && error.Code != StatusCodes.Good) { diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, error); diagnosticsExist = true; } } } // clear diagnostics if not required. if (!diagnosticsExist && diagnosticInfos != null) { diagnosticInfos.Clear(); } // update diagnostics. lock (m_diagnostics) { m_diagnostics.MonitoredItemCount = 0; m_diagnostics.DisabledMonitoredItemCount = 0; } if (monitoringMode == MonitoringMode.Disabled) { // TraceState("ITEMS DISABLED"); } else if (monitoringMode == MonitoringMode.Reporting) { // TraceState("ITEMS REPORTING ENABLED"); } else { // TraceState("ITEMS SAMPLING ENABLED"); } } }
/// <summary> /// Fills in the diagnostic information after an error. /// </summary> public static bool CreateError( uint code, StatusCodeCollection results, DiagnosticInfoCollection diagnosticInfos, int index, OperationContext context) { ServiceResult error = new ServiceResult(code); results[index] = error.Code; if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { diagnosticInfos[index] = new DiagnosticInfo(error, context.DiagnosticsMask, false, context.StringTable); return true; } return false; }