/// <summary>
 /// Constructs a new instance.
 /// </summary>
 public DataChangeMonitoredItem(
     MonitoredNode source,
     uint id,
     uint attributeId,
     NumericRange indexRange,
     QualifiedName dataEncoding,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     double samplingInterval,
     bool alwaysReportUpdates)
 {
     m_source = source;
     m_id = id;
     m_attributeId = attributeId;
     m_indexRange = indexRange;
     m_dataEncoding = dataEncoding;
     m_timestampsToReturn = timestampsToReturn;
     m_diagnosticsMasks = diagnosticsMasks;
     m_monitoringMode = monitoringMode;
     m_clientHandle = clientHandle;
     m_samplingInterval = samplingInterval;
     m_nextSampleTime = DateTime.UtcNow.Ticks;
     m_readyToPublish = false;
     m_readyToTrigger = false;
     m_alwaysReportUpdates = alwaysReportUpdates;
 }
Esempio n. 2
0
        public static Entry For(TimestampsToReturn timestampsToReturn)
        {
            String ttrText = null;

            switch (timestampsToReturn)
            {
            case TimestampsToReturn.Source:
                ttrText = "Source";
                break;

            case TimestampsToReturn.Server:
                ttrText = "Server";
                break;

            case TimestampsToReturn.Both:
                ttrText = "Both";
                break;

            case TimestampsToReturn.Neither:
                ttrText = "Neither";
                break;

            case TimestampsToReturn.Invalid:
                ttrText = "Invalid";
                break;
            }
            return(new StringEntry(ttrText));
        }
Esempio n. 3
0
        /// <summary>
        /// Used by the performance test.
        /// </summary>
        public override ResponseHeader Read(
            RequestHeader requestHeader,
            double maxAge,
            TimestampsToReturn timestampsToReturn,
            ReadValueIdCollection nodesToRead,
            out DataValueCollection values,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            if (requestHeader.ReturnDiagnostics != 5000)
            {
                return(base.Read(requestHeader, maxAge, timestampsToReturn, nodesToRead, out values, out diagnosticInfos));
            }

            diagnosticInfos = null;

            DataValue value = new DataValue();

            value.WrappedValue    = new Variant((int)1);
            value.SourceTimestamp = DateTime.UtcNow;

            values = new DataValueCollection(nodesToRead.Count);

            foreach (ReadValueId valueId in nodesToRead)
            {
                values.Add(value);
            }

            return(new ResponseHeader());
        }
Esempio n. 4
0
 /// <summary>
 /// Constructs a new instance.
 /// </summary>
 public DataChangeMonitoredItem(
     MonitoredNode source,
     uint id,
     uint attributeId,
     NumericRange indexRange,
     QualifiedName dataEncoding,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     double samplingInterval,
     bool alwaysReportUpdates)
 {
     m_source              = source;
     m_id                  = id;
     m_attributeId         = attributeId;
     m_indexRange          = indexRange;
     m_dataEncoding        = dataEncoding;
     m_timestampsToReturn  = timestampsToReturn;
     m_diagnosticsMasks    = diagnosticsMasks;
     m_monitoringMode      = monitoringMode;
     m_clientHandle        = clientHandle;
     m_samplingInterval    = samplingInterval;
     m_nextSampleTime      = HiResClock.TickCount64;
     m_readyToPublish      = false;
     m_readyToTrigger      = false;
     m_alwaysReportUpdates = alwaysReportUpdates;
 }
Esempio n. 5
0
 /// <summary>
 /// Creates a new data change monitored item.
 /// </summary>
 /// <param name="context">The system context.</param>
 /// <param name="monitoredItemId">The unique identifier for the monitored item.</param>
 /// <param name="attributeId">The attribute to monitor.</param>
 /// <param name="indexRange">The index range to use for array values.</param>
 /// <param name="dataEncoding">The data encoding to return for structured values.</param>
 /// <param name="diagnosticsMasks">The diagnostics masks to use.</param>
 /// <param name="timestampsToReturn">The timestamps to return.</param>
 /// <param name="monitoringMode">The initial monitoring mode.</param>
 /// <param name="clientHandle">The handle assigned by the client.</param>
 /// <param name="samplingInterval">The sampling interval.</param>
 /// <param name="alwaysReportUpdates">Whether the monitored item should skip the check for a change in value.</param>
 /// <returns>The new monitored item.</returns>
 public DataChangeMonitoredItem CreateDataChangeItem(
     ISystemContext context,
     uint monitoredItemId,
     uint attributeId,
     NumericRange indexRange,
     QualifiedName dataEncoding,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     double samplingInterval,
     bool alwaysReportUpdates)
 {
     return(CreateDataChangeItem(
                context,
                monitoredItemId,
                attributeId,
                indexRange,
                dataEncoding,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                samplingInterval,
                0,
                false,
                null,
                null,
                alwaysReportUpdates));
 }
Esempio n. 6
0
 /// <summary>
 /// Constructs a new instance.
 /// </summary>
 public DataChangeMonitoredItem(
     MonitoredNode source,
     uint id,
     uint attributeId,
     NumericRange indexRange,
     QualifiedName dataEncoding,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     double samplingInterval,
     bool alwaysReportUpdates)
 {
     _source             = source;
     Id                  = id;
     AttributeId         = attributeId;
     IndexRange          = indexRange;
     DataEncoding        = dataEncoding;
     _timestampsToReturn = timestampsToReturn;
     _diagnosticsMasks   = diagnosticsMasks;
     MonitoringMode      = monitoringMode;
     ClientHandle        = clientHandle;
     _samplingInterval   = samplingInterval;
     _nextSampleTime     = DateTime.UtcNow.Ticks;
     _readyToPublish     = false;
     _readyToTrigger     = false;
     AlwaysReportUpdates = alwaysReportUpdates;
 }
Esempio n. 7
0
        /// <summary>
        /// Modifies a monitored item.
        /// </summary>
        public void ModifyMonitoredItem(
            OperationContext context,
            IEventMonitoredItem monitoredItem,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemModifyRequest itemToModify,
            EventFilter filter)
        {
            lock (m_lock) {
                // should never be called with items that it does not own.
                if (!m_monitoredItems.ContainsKey(monitoredItem.Id))
                {
                    return;
                }

                // limit the queue size.
                uint queueSize = itemToModify.RequestedParameters.QueueSize;

                if (queueSize > m_maxEventQueueSize)
                {
                    queueSize = m_maxEventQueueSize;
                }

                // modify the attributes.
                monitoredItem.ModifyAttributes(
                    context.DiagnosticsMask,
                    timestampsToReturn,
                    itemToModify.RequestedParameters.ClientHandle,
                    filter,
                    filter,
                    null,
                    itemToModify.RequestedParameters.SamplingInterval,
                    queueSize,
                    itemToModify.RequestedParameters.DiscardOldest);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Adds a DataValue to a list of values to return.
        /// </summary>
        private void AddValue(
            TimestampsToReturn timestampsToReturn,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values,
            DataValue value)
        {
            // ignore invalid case.
            if (value == null)
            {
                return;
            }

            // save the last timestamp returned.
            m_lastTime = value.ServerTimestamp;

            // check if the index range or data encoding can be applied.
            if (StatusCode.IsGood(value.StatusCode))
            {
                object valueToReturn = value.Value;

                // apply the index range.
                if (indexRange != NumericRange.Empty)
                {
                    StatusCode error = indexRange.ApplyRange(ref valueToReturn);

                    if (StatusCode.IsBad(error))
                    {
                        value.Value      = null;
                        value.StatusCode = error;
                    }
                    else
                    {
                        value.Value = valueToReturn;
                    }
                }

                // apply the data encoding.
                if (!QualifiedName.IsNull(dataEncoding))
                {
                    value.Value      = null;
                    value.StatusCode = StatusCodes.BadDataEncodingUnsupported;
                }
            }

            // apply the timestamps filter.
            if (timestampsToReturn == TimestampsToReturn.Neither || timestampsToReturn == TimestampsToReturn.Server)
            {
                value.SourceTimestamp = DateTime.MinValue;
            }

            if (timestampsToReturn == TimestampsToReturn.Neither || timestampsToReturn == TimestampsToReturn.Source)
            {
                value.ServerTimestamp = DateTime.MinValue;
            }

            // add result.
            values.Add(value);
        }
Esempio n. 9
0
 /// <summary>
 /// Modifies the monitored item parameters,
 /// </summary>
 public ServiceResult Modify(
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     uint clientHandle,
     double samplingInterval)
 {
     return(Modify(diagnosticsMasks, timestampsToReturn, clientHandle, samplingInterval, 0, false, null, null));
 }
Esempio n. 10
0
            public ContinuationPointHistory(object Details, TimestampsToReturn ReturnTimes, HistoryReadValueId ReadId)
            {
                this.Details     = Details;
                this.ReturnTimes = ReturnTimes;
                this.ReadId      = ReadId;

                IsValid = false;
                Offset  = 0;
            }
Esempio n. 11
0
        /// <summary>
        /// Creates a set of monitored items.
        /// </summary>
        public MonitoredItem CreateMonitoredItem(
            OperationContext context,
            INodeManager nodeManager,
            object handle,
            uint subscriptionId,
            uint monitoredItemId,
            TimestampsToReturn timestampsToReturn,
            double publishingInterval,
            MonitoredItemCreateRequest itemToCreate,
            EventFilter filter)
        {
            lock (m_lock)
            {
                // calculate sampling interval.
                double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

                if (samplingInterval < 0)
                {
                    samplingInterval = publishingInterval;
                }

                // limit the queue size.
                uint queueSize = itemToCreate.RequestedParameters.QueueSize;

                if (queueSize > m_maxEventQueueSize)
                {
                    queueSize = m_maxEventQueueSize;
                }

                // create the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem(
                    m_server,
                    nodeManager,
                    handle,
                    subscriptionId,
                    monitoredItemId,
                    context.Session,
                    itemToCreate.ItemToMonitor,
                    context.DiagnosticsMask,
                    timestampsToReturn,
                    itemToCreate.MonitoringMode,
                    itemToCreate.RequestedParameters.ClientHandle,
                    filter,
                    filter,
                    null,
                    samplingInterval,
                    queueSize,
                    itemToCreate.RequestedParameters.DiscardOldest,
                    MinimumSamplingIntervals.Continuous);

                // save the monitored item.
                m_monitoredItems.Add(monitoredItemId, monitoredItem);

                return(monitoredItem);
            }
        }
Esempio n. 12
0
 public ResponseHeader ModifyMonitoredItems(
     RequestHeader requestHeader,
     uint subscriptionId,
     TimestampsToReturn timestampsToReturn,
     MonitoredItemModifyRequestCollection itemsToModify,
     out MonitoredItemModifyResultCollection results,
     out DiagnosticInfoCollection diagnosticInfos)
 {
     return(m_session.ModifyMonitoredItems(requestHeader, subscriptionId, timestampsToReturn, itemsToModify, out results, out diagnosticInfos));
 }
Esempio n. 13
0
        /// <summary>
        /// Modifies the parameters for a monitored item.
        /// </summary>
        protected override ServiceResult ModifyMonitoredItem(
            ISystemContext context,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            IMonitoredItem monitoredItem,
            MonitoredItemModifyRequest itemToModify,
            out MonitoringFilterResult filterError)
        {
            filterError = null;

            // check for valid handle.
            MemoryBufferState buffer = monitoredItem.ManagerHandle as MemoryBufferState;

            if (buffer == null)
            {
                return(base.ModifyMonitoredItem(
                           context,
                           diagnosticsMasks,
                           timestampsToReturn,
                           monitoredItem,
                           itemToModify,
                           out filterError));
            }

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

            // get the monitored item.
            MemoryBufferMonitoredItem datachangeItem = monitoredItem as MemoryBufferMonitoredItem;

            if (datachangeItem == null)
            {
                return(StatusCodes.BadMonitoredItemIdInvalid);
            }

            // validate parameters.
            MonitoringParameters parameters = itemToModify.RequestedParameters;

            // no filters supported at this time.
            MonitoringFilter filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter);

            if (filter != null)
            {
                return(StatusCodes.BadFilterNotAllowed);
            }

            // modify the monitored item parameters.
            ServiceResult error = datachangeItem.Modify(
                diagnosticsMasks,
                timestampsToReturn,
                itemToModify.RequestedParameters.ClientHandle,
                itemToModify.RequestedParameters.SamplingInterval);

            return(ServiceResult.Good);
        }
Esempio n. 14
0
 public ResponseHeader CreateMonitoredItems(
     RequestHeader requestHeader,
     uint subscriptionId,
     TimestampsToReturn timestampsToReturn,
     MonitoredItemCreateRequestCollection itemsToCreate,
     out MonitoredItemCreateResultCollection results,
     out DiagnosticInfoCollection diagnosticInfos)
 {
     return(m_server.CreateMonitoredItems(requestHeader, subscriptionId, timestampsToReturn, itemsToCreate,
                                          out results, out diagnosticInfos));
 }
Esempio n. 15
0
 /// <summary>
 /// Reads the data at the specified time for an item.
 /// </summary>
 protected override void HistoryReadAtTime(
     UaServerContext context,
     ReadAtTimeDetails details,
     TimestampsToReturn timestampsToReturn,
     IList <HistoryReadValueId> nodesToRead,
     IList <HistoryReadResult> results,
     IList <ServiceResult> errors,
     List <UaNodeHandle> nodesToProcess,
     IDictionary <NodeId, NodeState> cache)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        public DataChangeMonitoredItem(
            MonitoredNode source,
            uint id,
            uint attributeId,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoringMode monitoringMode,
            uint clientHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            DataChangeFilter filter,
            Range range,
            bool alwaysReportUpdates)
        {
            m_source              = source;
            m_id                  = id;
            m_attributeId         = attributeId;
            m_indexRange          = indexRange;
            m_dataEncoding        = dataEncoding;
            m_timestampsToReturn  = timestampsToReturn;
            m_diagnosticsMasks    = diagnosticsMasks;
            m_monitoringMode      = monitoringMode;
            m_clientHandle        = clientHandle;
            m_samplingInterval    = samplingInterval;
            m_nextSampleTime      = DateTime.UtcNow.Ticks;
            m_readyToPublish      = false;
            m_readyToTrigger      = false;
            m_resendData          = false;
            m_queue               = null;
            m_filter              = filter;
            m_range               = 0;
            m_alwaysReportUpdates = alwaysReportUpdates;

            if (range != null)
            {
                m_range = range.High - range.Low;
            }

            if (queueSize > 1)
            {
                m_queue = new MonitoredItemQueue(id);
                m_queue.SetQueueSize(queueSize, discardOldest, diagnosticsMasks);
                m_queue.SetSamplingInterval(samplingInterval);
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        public DataChangeMonitoredItem(
            MonitoredNode source,
            uint id,
            uint attributeId,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoringMode monitoringMode,
            uint clientHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            DataChangeFilter filter,
            Range range,
            bool alwaysReportUpdates)
        {
            m_source = source;
            m_id = id;
            m_attributeId = attributeId;
            m_indexRange = indexRange;
            m_dataEncoding = dataEncoding;
            m_timestampsToReturn = timestampsToReturn;
            m_diagnosticsMasks = diagnosticsMasks;
            m_monitoringMode = monitoringMode;
            m_clientHandle = clientHandle;
            m_samplingInterval = samplingInterval;
            m_nextSampleTime = DateTime.UtcNow.Ticks;
            m_readyToPublish = false;
            m_readyToTrigger = false;
            m_queue = null;
            m_filter = filter;
            m_range = 0;
            m_alwaysReportUpdates = alwaysReportUpdates;
        
            if (range != null)
            {
                m_range = range.High  - range.Low;
            }

            if (queueSize > 1)
            {
                m_queue = new MonitoredItemQueue();
                m_queue.SetQueueSize(queueSize, discardOldest, diagnosticsMasks);
                m_queue.SetSamplingInterval(samplingInterval);
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Invokes the Read service.
        /// </summary>
        public virtual ResponseHeader Read(
            RequestHeader requestHeader,
            double maxAge,
            TimestampsToReturn timestampsToReturn,
            ReadValueIdCollection nodesToRead,
            out DataValueCollection results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results         = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return(CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported));
        }
Esempio n. 19
0
        /// <summary>
        /// Invokes the ModifyMonitoredItems service.
        /// </summary>
        public virtual ResponseHeader ModifyMonitoredItems(
            RequestHeader requestHeader,
            uint subscriptionId,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemModifyRequestCollection itemsToModify,
            out MonitoredItemModifyResultCollection results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results         = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return(CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported));
        }
Esempio n. 20
0
        /// <summary>
        /// Creates a new data change monitored item.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="monitoredItemId">The unique identifier for the monitiored item.</param>
        /// <param name="attributeId">The attribute to monitor.</param>
        /// <param name="indexRange">The index range to use for array values.</param>
        /// <param name="dataEncoding">The data encoding to return for structured values.</param>
        /// <param name="diagnosticsMasks">The diagnostics masks to use.</param>
        /// <param name="timestampsToReturn">The timestamps to return.</param>
        /// <param name="monitoringMode">The initial monitoring mode.</param>
        /// <param name="clientHandle">The handle assigned by the client.</param>
        /// <param name="samplingInterval">The sampling interval.</param>
        /// <param name="queueSize">The queue size.</param>
        /// <param name="discardOldest">Whether to discard the oldest values when the queue overflows.</param>
        /// <param name="filter">The data change filter to use.</param>
        /// <param name="range">The range to use when evaluating a percentage deadband filter.</param>
        /// <param name="alwaysReportUpdates">Whether the monitored item should skip the check for a change in value.</param>
        /// <returns>The new monitored item.</returns>
        public DataChangeMonitoredItem CreateDataChangeItem(
            ISystemContext context,
            uint monitoredItemId,
            uint attributeId,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoringMode monitoringMode,
            uint clientHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            DataChangeFilter filter,
            Range range,
            bool alwaysReportUpdates)
        {
            System.Diagnostics.Contracts.Contract.Assume(context != null);
            var monitoredItem = new DataChangeMonitoredItem(
                this,
                monitoredItemId,
                attributeId,
                indexRange,
                dataEncoding,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                samplingInterval,
                queueSize,
                discardOldest,
                filter,
                range,
                alwaysReportUpdates);

            if (_monitoredItems == null)
            {
                _monitoredItems     = new List <DataChangeMonitoredItem>();
                Node.OnStateChanged = OnNodeChange;
            }

            _monitoredItems.Add(monitoredItem);

            return(monitoredItem);
        }
        /// <summary>
        /// Continues a read raw operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        /// <param name="timestampsToReturn">The timestamps to return with the value.</param>
        /// <param name="indexRange">The range to return for array values.</param>
        /// <param name="dataEncoding">The data encoding to use for structured values.</param>
        /// <param name="values">The values to return.</param>
        /// <returns>False if the operation halted because the maximum number of values was discovered.</returns>
        public bool NextReadRaw(
#pragma warning disable RECS0154 // Parameter is never used
#pragma warning disable IDE0060  // Remove unused parameter
            ServerSystemContext context,
#pragma warning restore IDE0060  // Remove unused parameter
#pragma warning restore RECS0154 // Parameter is never used
            TimestampsToReturn timestampsToReturn,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values)
        {
            DataValue value = null;

            do
            {
                // check for limit.
                if (_request.NumValuesPerNode > 0 && values.Count >= _request.NumValuesPerNode)
                {
                    return(false);
                }

                value = _source.NextRaw(_lastTime, _isForward, _request.IsReadModified, ref _position);

                // no more data.
                if (value == null)
                {
                    return(true);
                }

                // check for bound.
                if ((_isForward && value.ServerTimestamp >= _endTime) || (!_isForward && value.ServerTimestamp <= _endTime))
                {
                    if (_request.ReturnBounds)
                    {
                        AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
                        return(true);
                    }
                }

                // add value.
                AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
            }while (value != null);

            return(true);
        }
Esempio n. 22
0
        /// <summary>
        /// Invokes the HistoryRead service.
        /// </summary>
        public virtual ResponseHeader HistoryRead(
            RequestHeader requestHeader,
            ExtensionObject historyReadDetails,
            TimestampsToReturn timestampsToReturn,
            bool releaseContinuationPoints,
            HistoryReadValueIdCollection nodesToRead,
            out HistoryReadResultCollection results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results         = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return(CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported));
        }
Esempio n. 23
0
        /// <summary>
        /// Creates a monitored item.
        /// </summary>
        public void CreateMonitoredItem(
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest request,
            MonitoredItemCreateResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // initialize the monitored item.
                MonitoredItem monitoredItem = new MonitoredItem();

                monitoredItem.Id             = (uint)Interlocked.Increment(ref m_monitoredItemCounter);
                monitoredItem.ItemToMonitor  = request.ItemToMonitor;
                monitoredItem.MonitoringMode = request.MonitoringMode;
                monitoredItem.Parameters     = request.RequestedParameters;
                monitoredItem.NextScanTime   = 0;

                // use the publishing interval as the default.
                if (monitoredItem.Parameters.SamplingInterval < 0)
                {
                    monitoredItem.Parameters.SamplingInterval = m_publishingInterval;
                }

                // ensure the queue is at least one.
                if (monitoredItem.Parameters.QueueSize == 0)
                {
                    monitoredItem.Parameters.QueueSize = 1;
                }

                result.MonitoredItemId         = monitoredItem.Id;
                result.RevisedQueueSize        = monitoredItem.Parameters.QueueSize;
                result.RevisedSamplingInterval = monitoredItem.Parameters.SamplingInterval;
                result.FilterResult            = new ExtensionObject();

                m_monitoredItems.Add(monitoredItem.Id, monitoredItem);

                // start a background thread that scans the items.
                if (m_monitoredItems.Count == 1)
                {
                    ThreadPool.QueueUserWorkItem(OnScanItems);
                }
            }
        }
		/// <summary>
		/// Initializes the object with its node type.
		/// </summary>
        public MemoryBufferMonitoredItem(
            IServerInternal     server,
            INodeManager        nodeManager,
            object              mangerHandle,
            uint                offset,
            uint                subscriptionId,
            uint                id,
            Session             session,
            ReadValueId         itemToMonitor,
            DiagnosticsMasks    diagnosticsMasks,
            TimestampsToReturn  timestampsToReturn,
            MonitoringMode      monitoringMode,
            uint                clientHandle,
            MonitoringFilter    originalFilter,
            MonitoringFilter    filterToUse,
            Range               range,
            double              samplingInterval,
            uint                queueSize,
            bool                discardOldest,
            double              minimumSamplingInterval)
        :
            base(
                server,
                nodeManager,
                mangerHandle,
                subscriptionId,
                id,
                session,
                itemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                originalFilter,
                filterToUse,
                range,
                samplingInterval,
                queueSize,
                discardOldest,
                minimumSamplingInterval)
		{
            m_offset = offset;
        }
Esempio n. 25
0
 /// <summary>
 /// Initializes the object with its node type.
 /// </summary>
 public MemoryBufferMonitoredItem(
     IServerInternal server,
     INodeManager nodeManager,
     object mangerHandle,
     uint offset,
     uint subscriptionId,
     uint id,
     Session session,
     ReadValueId itemToMonitor,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     MonitoringFilter originalFilter,
     MonitoringFilter filterToUse,
     Range range,
     double samplingInterval,
     uint queueSize,
     bool discardOldest,
     double minimumSamplingInterval)
     :
     base(
         server,
         nodeManager,
         mangerHandle,
         subscriptionId,
         id,
         session,
         itemToMonitor,
         diagnosticsMasks,
         timestampsToReturn,
         monitoringMode,
         clientHandle,
         originalFilter,
         filterToUse,
         range,
         samplingInterval,
         queueSize,
         discardOldest,
         minimumSamplingInterval)
 {
     m_offset = offset;
 }
Esempio n. 26
0
        /// <summary>
        /// Continues a read raw operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        /// <param name="timestampsToReturn">The timestamps to return with the value.</param>
        /// <param name="indexRange">The range to return for array values.</param>
        /// <param name="dataEncoding">The data encoding to use for structured values.</param>
        /// <param name="values">The values to return.</param>
        /// <returns>False if the operation halted because the maximum number of values was discovered.</returns>
        public bool NextReadRaw(
            ServerSystemContext context,
            TimestampsToReturn timestampsToReturn,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values)
        {
            DataValue value = null;

            do
            {
                // check for limit.
                if (m_request.NumValuesPerNode > 0 && values.Count >= m_request.NumValuesPerNode)
                {
                    return(false);
                }

                value = m_source.NextRaw(m_lastTime, m_isForward, m_request.IsReadModified, ref m_position);

                // no more data.
                if (value == null)
                {
                    return(true);
                }

                // check for bound.
                if ((m_isForward && value.ServerTimestamp >= m_endTime) ||
                    (!m_isForward && value.ServerTimestamp <= m_endTime))
                {
                    if (m_request.ReturnBounds)
                    {
                        AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
                        return(true);
                    }
                }

                // add value.
                AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
            } while (value != null);

            return(true);
        }
Esempio n. 27
0
 public MonitoredItem CreateMonitoredItem(
     OperationContext context,
     INodeManager nodeManager,
     object handle,
     uint subscriptionId,
     uint monitoredItemId,
     TimestampsToReturn timestampsToReturn,
     MonitoredItemCreateRequest itemToCreate,
     EventFilter filter)
 {
     return(CreateMonitoredItem(
                context,
                nodeManager,
                handle,
                subscriptionId,
                monitoredItemId,
                timestampsToReturn,
                0,
                itemToCreate,
                filter));
 }
        /// <summary>
        /// Starts reading raw values.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        /// <param name="request">The request parameters.</param>
        /// <param name="timestampsToReturn">The timestamps to return with the value.</param>
        /// <param name="indexRange">The range to return for array values.</param>
        /// <param name="dataEncoding">The data encoding to use for structured values.</param>
        /// <param name="values">The values to return.</param>
        public void BeginReadRaw(
#pragma warning disable RECS0154 // Parameter is never used
#pragma warning disable IDE0060  // Remove unused parameter
            ServerSystemContext context,
#pragma warning restore IDE0060  // Remove unused parameter
#pragma warning restore RECS0154 // Parameter is never used
            ReadRawModifiedDetails request,
            TimestampsToReturn timestampsToReturn,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values)
        {
            _request = request;

            // initialize start and end.
            _startTime = _request.StartTime;
            _endTime   = _request.EndTime;

            if (_endTime == DateTime.MinValue)
            {
                _endTime = DateTime.MaxValue;
            }

            // check the direction.
            _isForward = _startTime < _endTime;
            _position  = -1;

            DataValue value = null;

            // get first bound.
            if (_request.ReturnBounds)
            {
                value = _source.FirstRaw(_startTime, !_isForward, _request.IsReadModified, out _position);

                if (value != null)
                {
                    AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
                }
            }
        }
Esempio n. 29
0
 /// <summary>
 /// Creates a new monitored item.
 /// </summary>
 /// <param name="server">The server.</param>
 /// <param name="nodeManager">The node manager.</param>
 /// <param name="managerHandle">The manager handle.</param>
 /// <param name="subscriptionId">The subscription id.</param>
 /// <param name="id">The id.</param>
 /// <param name="session">The session.</param>
 /// <param name="itemToMonitor">The item to monitor.</param>
 /// <param name="diagnosticsMasks">The diagnostics masks.</param>
 /// <param name="timestampsToReturn">The timestamps to return.</param>
 /// <param name="monitoringMode">The monitoring mode.</param>
 /// <param name="clientHandle">The client handle.</param>
 /// <param name="originalFilter">The original filter.</param>
 /// <param name="filterToUse">The filter to use.</param>
 /// <param name="range">The range.</param>
 /// <param name="samplingInterval">The sampling interval.</param>
 /// <param name="queueSize">Size of the queue.</param>
 /// <param name="discardOldest">if set to <c>true</c> [discard oldest].</param>
 /// <param name="minimumSamplingInterval">The minimum sampling interval.</param>
 /// <returns>The monitored item.</returns>
 protected virtual MonitoredItem CreateMonitoredItem(
     IServerInternal server,
     INodeManager nodeManager,
     object managerHandle,
     uint subscriptionId,
     uint id,
     Session session,
     ReadValueId itemToMonitor,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     MonitoringFilter originalFilter,
     MonitoringFilter filterToUse,
     Range range,
     double samplingInterval,
     uint queueSize,
     bool discardOldest,
     double minimumSamplingInterval)
 {
     return(new MonitoredItem(
                server,
                nodeManager,
                managerHandle,
                subscriptionId,
                id,
                session,
                itemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                originalFilter,
                filterToUse,
                range,
                samplingInterval,
                queueSize,
                discardOldest,
                minimumSamplingInterval));
 }
Esempio n. 30
0
        /// <summary>
        /// Starts reading raw values.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        /// <param name="request">The request parameters.</param>
        /// <param name="timestampsToReturn">The timestamps to return with the value.</param>
        /// <param name="indexRange">The range to return for array values.</param>
        /// <param name="dataEncoding">The data encoding to use for structured values.</param>
        /// <param name="values">The values to return.</param>
        public void BeginReadRaw(
            ServerSystemContext context,
            ReadRawModifiedDetails request,
            TimestampsToReturn timestampsToReturn,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DataValueCollection values)
        {
            m_request = request;

            // initialize start and end.
            m_startTime = m_request.StartTime;
            m_endTime   = m_request.EndTime;

            if (m_endTime == DateTime.MinValue)
            {
                m_endTime = DateTime.MaxValue;
            }

            // check the direction.
            m_isForward = m_startTime < m_endTime;
            m_position  = -1;

            DataValue value = null;

            // get first bound.
            if (m_request.ReturnBounds)
            {
                value = m_source.FirstRaw(m_startTime, !m_isForward, m_request.IsReadModified, out m_position);

                if (value != null)
                {
                    AddValue(timestampsToReturn, indexRange, dataEncoding, values, value);
                }
            }
        }
        /// <summary>
        /// Reads the history for the specified nodes.
        /// </summary>
        public virtual void HistoryRead(
            OperationContext          context, 
            HistoryReadDetails        details, 
            TimestampsToReturn        timestampsToReturn, 
            bool                      releaseContinuationPoints, 
            IList<HistoryReadValueId> nodesToRead, 
            IList<HistoryReadResult>  results, 
            IList<ServiceResult>      errors)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();
            List<ReadWriteOperationState> nodesToValidate = new List<ReadWriteOperationState>();
            List<ReadWriteOperationState> readsToComplete = new List<ReadWriteOperationState>();

            lock (Lock)
            {
                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {                    
                    HistoryReadValueId nodeToRead = nodesToRead[ii];

                    // skip items that have already been processed.
                    if (nodeToRead.Processed)
                    {
                        continue;
                    }
                    
                    // check for valid handle.
                    NodeState source = GetManagerHandle(systemContext, nodeToRead.NodeId, operationCache) as NodeState;

                    if (source == null)
                    {
                        continue;
                    }

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

                    // only variables supported.
                    BaseVariableState variable = source as BaseVariableState;

                    if (variable == null)
                    {
                        errors[ii] = StatusCodes.BadHistoryOperationUnsupported;
                        continue;
                    }
                    
                    results[ii] = new HistoryReadResult();
                    
                    ReadWriteOperationState operation = new ReadWriteOperationState();
                    
                    operation.Source = source;
                    operation.Index = ii;

                    // check if the node is ready for reading.
                    if (source.ValidationRequired)
                    {
                        // must validate node in a seperate operation.
                        errors[ii] = StatusCodes.BadNodeIdUnknown;
                        nodesToValidate.Add(operation);                        
                        continue;
                    }

                    // read the data.
                    readsToComplete.Add(operation);
                }

                // validates the nodes (reads values from the underlying data source if required).
                for (int ii = 0; ii < nodesToValidate.Count; ii++)
                {
                    ReadWriteOperationState operation = nodesToValidate[ii];

                    if (!ValidateNode(systemContext, operation.Source))
                    {
                        continue;
                    }

                    readsToComplete.Add(operation);
                }
            }

            // reads the data without holding onto the lock.
            for (int ii = 0; ii < readsToComplete.Count; ii++)
            {
                ReadWriteOperationState operation = readsToComplete[ii];

                errors[operation.Index] = HistoryRead(
                    systemContext,
                    operation.Source,
                    details,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead[operation.Index],
                    results[operation.Index]);
            }
        }
 /// <summary>
 /// Creates a new data change monitored item.
 /// </summary>
 /// <param name="context">The system context.</param>
 /// <param name="monitoredItemId">The unique identifier for the monitiored item.</param>
 /// <param name="attributeId">The attribute to monitor.</param>
 /// <param name="indexRange">The index range to use for array values.</param>
 /// <param name="dataEncoding">The data encoding to return for structured values.</param>
 /// <param name="diagnosticsMasks">The diagnostics masks to use.</param>
 /// <param name="timestampsToReturn">The timestamps to return.</param>
 /// <param name="monitoringMode">The initial monitoring mode.</param>
 /// <param name="clientHandle">The handle assigned by the client.</param>
 /// <param name="samplingInterval">The sampling interval.</param>
 /// <param name="alwaysReportUpdates">Whether the monitored item should skip the check for a change in value.</param>
 /// <returns>The new monitored item.</returns>
 public DataChangeMonitoredItem CreateDataChangeItem(
     ISystemContext context,
     uint monitoredItemId,
     uint attributeId,
     NumericRange indexRange,
     QualifiedName dataEncoding,
     DiagnosticsMasks diagnosticsMasks,
     TimestampsToReturn timestampsToReturn,
     MonitoringMode monitoringMode,
     uint clientHandle,
     double samplingInterval,
     bool alwaysReportUpdates)
 {
     return CreateDataChangeItem(
         context,
         monitoredItemId,
         attributeId,
         indexRange,
         dataEncoding,
         diagnosticsMasks,
         timestampsToReturn,
         monitoringMode,
         clientHandle,
         samplingInterval,
         0,
         false,
         null,
         null,
         alwaysReportUpdates);
 }
        /// <summary>
        /// Invokes the HistoryRead service.
        /// </summary>
        public virtual ResponseHeader HistoryRead(
            RequestHeader                   requestHeader,
            ExtensionObject                 historyReadDetails,
            TimestampsToReturn              timestampsToReturn,
            bool                            releaseContinuationPoints,
            HistoryReadValueIdCollection    nodesToRead,
            out HistoryReadResultCollection results,
            out DiagnosticInfoCollection    diagnosticInfos)
        {
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
		/// <summary>
		/// Initializes the object with its node type.
		/// </summary>
        public MonitoredItem(
            IServerInternal     server,
            INodeManager        nodeManager,
            object              mangerHandle,
            uint                subscriptionId,
            uint                id,
            Session             session,
            ReadValueId         itemToMonitor,
            DiagnosticsMasks    diagnosticsMasks,
            TimestampsToReturn  timestampsToReturn,
            MonitoringMode      monitoringMode,
            uint                clientHandle,
            MonitoringFilter    originalFilter,
            MonitoringFilter    filterToUse,
            Range               range,
            double              samplingInterval,
            uint                queueSize,
            bool                discardOldest,
            double              sourceSamplingInterval)
		{
            if (itemToMonitor == null) throw new ArgumentNullException("itemToMonitor");
            
			Initialize();
            
            m_server                  = server;
            m_nodeManager             = nodeManager;
            m_managerHandle           = mangerHandle;
            m_subscriptionId          = subscriptionId;
            m_id                      = id;
            m_session                 = session;
            m_nodeId                  = itemToMonitor.NodeId;
            m_attributeId             = itemToMonitor.AttributeId;
            m_indexRange              = itemToMonitor.IndexRange;
            m_parsedIndexRange        = itemToMonitor.ParsedIndexRange;
            m_encoding                = itemToMonitor.DataEncoding;
            m_diagnosticsMasks        = diagnosticsMasks;
            m_timestampsToReturn      = timestampsToReturn;
            m_monitoringMode          = monitoringMode;
            m_clientHandle            = clientHandle;
            m_originalFilter          = originalFilter;
            m_filterToUse             = filterToUse;
            m_range                   = 0;
            m_samplingInterval        = samplingInterval;
            m_queueSize               = queueSize;
            m_discardOldest           = discardOldest;
            m_sourceSamplingInterval  = (int)sourceSamplingInterval;
            m_calculator              = null;
            m_nextSamplingTime        = DateTime.UtcNow.Ticks;
            m_alwaysReportUpdates     = false;
            
            m_typeMask = MonitoredItemTypeMask.DataChange;

            if (originalFilter is EventFilter)
            {
                m_typeMask = MonitoredItemTypeMask.Events;

                if (itemToMonitor.NodeId == Objects.Server)
                {
                    m_typeMask |= MonitoredItemTypeMask.AllEvents;
                }
            }

            // create aggregate calculator.
            ServerAggregateFilter aggregateFilter = filterToUse as ServerAggregateFilter;

            if (filterToUse is ServerAggregateFilter)
            {
                m_calculator = m_server.AggregateManager.CreateCalculator(
                    aggregateFilter.AggregateType,
                    aggregateFilter.StartTime,
                    DateTime.MaxValue,
                    aggregateFilter.ProcessingInterval,
                    aggregateFilter.Stepped,
                    aggregateFilter.AggregateConfiguration);
            }

            if (range != null)
            {
                m_range = range.High - range.Low;
            }

            // report change to item state.
            ServerUtils.ReportCreateMonitoredItem(
                m_nodeId,
                m_id,
                m_samplingInterval,
                m_queueSize,
                m_discardOldest,
                m_filterToUse,
                m_monitoringMode);

            InitializeQueue();
		}
        /// <summary>
        /// Modifies the parameters for a set of monitored items.
        /// </summary>
        public virtual void ModifyMonitoredItems(
            OperationContext                  context, 
            TimestampsToReturn                timestampsToReturn, 
            IList<IMonitoredItem>             monitoredItems, 
            IList<MonitoredItemModifyRequest> itemsToModify, 
            IList<ServiceResult>              errors, 
            IList<MonitoringFilterResult>     filterErrors)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);

            lock (Lock)
            {
                for (int ii = 0; ii < monitoredItems.Count; ii++)
                {                    
                    MonitoredItemModifyRequest itemToModify = itemsToModify[ii];

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

                    // modify the monitored item.
                    MonitoringFilterResult filterError = null;

                    errors[ii] = ModifyMonitoredItem(
                        systemContext,
                        context.DiagnosticsMask,
                        timestampsToReturn,
                        monitoredItems[ii],
                        itemToModify,
                        out filterError);

                    // save any filter error details.
                    filterErrors[ii] = filterError;
                }
            }
        }
        /// <summary>
        /// Creates a new set of monitored items for a set of variables.
        /// </summary>
        /// <remarks>
        /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
        /// </remarks>
        public virtual void CreateMonitoredItems(
            OperationContext                  context, 
            uint                              subscriptionId, 
            double                            publishingInterval, 
            TimestampsToReturn                timestampsToReturn, 
            IList<MonitoredItemCreateRequest> itemsToCreate, 
            IList<ServiceResult>              errors, 
            IList<MonitoringFilterResult>     filterErrors, 
            IList<IMonitoredItem>             monitoredItems,
            ref long                          globalIdCounter)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();
            List<ReadWriteOperationState> nodesToValidate = new List<ReadWriteOperationState>();

            lock (Lock)
            {
                for (int ii = 0; ii < itemsToCreate.Count; ii++)
                {                    
                    MonitoredItemCreateRequest itemToCreate = itemsToCreate[ii];

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

                    ReadValueId itemToMonitor = itemToCreate.ItemToMonitor;
                                        
                    // check for valid handle.
                    NodeState source = GetManagerHandle(systemContext, itemToMonitor.NodeId, operationCache) as NodeState;

                    if (source == null)
                    {
                        continue;
                    }

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

                    // check if the node is ready for reading.
                    if (source.ValidationRequired)
                    {
                        errors[ii] = StatusCodes.BadNodeIdUnknown;
                        
                        // must validate node in a seperate operation.
                        ReadWriteOperationState operation = new ReadWriteOperationState();
                        
                        operation.Source = source;
                        operation.Index = ii;

                        nodesToValidate.Add(operation);

                        continue;
                    }

                    MonitoringFilterResult filterError = null;
                    IMonitoredItem monitoredItem = null;

                    errors[ii] = CreateMonitoredItem(
                        systemContext,
                        source,
                        subscriptionId,
                        publishingInterval,
                        context.DiagnosticsMask,
                        timestampsToReturn,
                        itemToCreate,
                        ref globalIdCounter,
                        out filterError,
                        out monitoredItem);

                    // save any filter error details.
                    filterErrors[ii] = filterError;

                    if (ServiceResult.IsBad(errors[ii]))
                    {
                        continue;
                    }

                    // save the monitored item.
                    monitoredItems[ii] = monitoredItem;
                }
                                
                // check for nothing to do.
                if (nodesToValidate.Count == 0)
                {
                    return;
                }

                // validates the nodes (reads values from the underlying data source if required).
                for (int ii = 0; ii < nodesToValidate.Count; ii++)
                {
                    ReadWriteOperationState operation = nodesToValidate[ii];

                    // validate the object.
                    if (!ValidateNode(systemContext, operation.Source))
                    {
                        continue;
                    }
                    
                    MonitoredItemCreateRequest itemToCreate = itemsToCreate[operation.Index];

                    MonitoringFilterResult filterError = null;
                    IMonitoredItem monitoredItem = null;

                    errors[operation.Index] = CreateMonitoredItem(
                        systemContext,
                        operation.Source,
                        subscriptionId,
                        publishingInterval,
                        context.DiagnosticsMask,
                        timestampsToReturn,
                        itemToCreate,
                        ref globalIdCounter,
                        out filterError,
                        out monitoredItem);

                    // save any filter error details.
                    filterErrors[operation.Index] = filterError;

                    if (ServiceResult.IsBad(errors[operation.Index]))
                    {
                        continue;
                    }

                    // save the monitored item.
                    monitoredItems[operation.Index] = monitoredItem;
                }
            }
        }
Esempio n. 37
0
        /// <summary>
        /// Reads the history of an HDA item.
        /// </summary>
        private ServiceResult HistoryReadItem(
            ServerSystemContext context,
            ComHdaClient client,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            HistoryReadValueId nodeToRead,
            HdaParsedNodeId parsedNodeId,
            HistoryReadResult result)
        { 
            // create the request or load it from a continuation point.
            HdaHistoryReadRawModifiedRequest request = null;

            if (nodeToRead.ContinuationPoint == null)
            {
                request = new HdaHistoryReadRawModifiedRequest(parsedNodeId.RootId, details, nodeToRead);
            }
            else
            {
                request = LoadContinuationPoint(context, nodeToRead.ContinuationPoint) as HdaHistoryReadRawModifiedRequest;

                if (request == null)
                {
                    return StatusCodes.BadContinuationPointInvalid;
                }
            }

            // fetch the data.
            result.StatusCode = client.ReadHistory(request);

            // fill in the results.
            if (request.Results != null)
            {
                HistoryData data = (request.IsReadModified)?new HistoryModifiedData():new HistoryData();

                if (request.IsReadModified)
                {
                    ((HistoryModifiedData)data).ModificationInfos = request.ModificationInfos;
                }

                data.DataValues = request.Results;
                result.HistoryData = new ExtensionObject(data);
            }

            // create a new continuation point.
            if (!request.Completed)
            {
                result.ContinuationPoint = SaveContinuationPoint(context, request);
            }

            return result.StatusCode;
        }
Esempio n. 38
0
        /// <summary>
        /// Modifies the monitored item parameters,
        /// </summary>
        public ServiceResult Modify(
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            uint clientHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            DataChangeFilter filter,
            Range range)
        {
            lock (m_lock)
            {
                m_diagnosticsMasks   = diagnosticsMasks;
                m_timestampsToReturn = timestampsToReturn;
                m_clientHandle       = clientHandle;

                // subtract the previous sampling interval.
                long oldSamplingInterval = (long)(m_samplingInterval * TimeSpan.TicksPerMillisecond);

                if (oldSamplingInterval < m_nextSampleTime)
                {
                    m_nextSampleTime -= oldSamplingInterval;
                }

                m_samplingInterval = samplingInterval;

                // calculate the next sampling interval.
                long newSamplingInterval = (long)(m_samplingInterval * TimeSpan.TicksPerMillisecond);

                if (m_samplingInterval > 0)
                {
                    m_nextSampleTime += newSamplingInterval;
                }
                else
                {
                    m_nextSampleTime = 0;
                }

                // update the filter and the range.
                m_filter = filter;
                m_range  = 0;

                if (range != null)
                {
                    m_range = range.High - range.Low;
                }

                // update the queue size.
                if (queueSize > 1)
                {
                    if (m_queue == null)
                    {
                        m_queue = new MonitoredItemQueue();
                    }

                    m_queue.SetQueueSize(queueSize, discardOldest, diagnosticsMasks);
                    m_queue.SetSamplingInterval(samplingInterval);
                }
                else
                {
                    m_queue = null;
                }

                return(ServiceResult.Good);
            }
        }
        /// <summary>
        /// Invokes the ModifyMonitoredItems service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="subscriptionId">The subscription id.</param>
        /// <param name="timestampsToReturn">The type of timestamps to be returned for the MonitoredItems.</param>
        /// <param name="itemsToModify">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 ModifyMonitoredItems(
            RequestHeader                           requestHeader, 
            uint                                    subscriptionId, 
            TimestampsToReturn                      timestampsToReturn,
            MonitoredItemModifyRequestCollection    itemsToModify, 
            out MonitoredItemModifyResultCollection results, 
            out DiagnosticInfoCollection            diagnosticInfos)
        {
            OperationContext context = ValidateRequest(requestHeader, RequestType.ModifyMonitoredItems);

            try
            {
                if (itemsToModify == null || itemsToModify.Count == 0)
                {
                    throw new ServiceResultException(StatusCodes.BadNothingToDo);
                }         

                ServerInternal.SubscriptionManager.ModifyMonitoredItems(
                    context,
                    subscriptionId,
                    timestampsToReturn,
                    itemsToModify,
                    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>
        /// Reads the raw data for a variable
        /// </summary>
        protected ServiceResult HistoryReadRaw(
            ISystemContext context,
            BaseVariableState source,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            bool releaseContinuationPoints,
            HistoryReadValueId nodeToRead,
            HistoryReadResult result)
        {
            ServerSystemContext serverContext = context as ServerSystemContext;

            HistoryDataReader reader = null;
            HistoryData       data   = new HistoryData();

            if (nodeToRead.ContinuationPoint != null && nodeToRead.ContinuationPoint.Length > 0)
            {
                // restore the continuation point.
                reader = RestoreDataReader(serverContext, nodeToRead.ContinuationPoint);

                if (reader == null)
                {
                    return(StatusCodes.BadContinuationPointInvalid);
                }

                // node id must match previous node id.
                if (reader.VariableId != nodeToRead.NodeId)
                {
                    Utils.SilentDispose(reader);
                    return(StatusCodes.BadContinuationPointInvalid);
                }

                // check if releasing continuation points.
                if (releaseContinuationPoints)
                {
                    Utils.SilentDispose(reader);
                    return(ServiceResult.Good);
                }
            }
            else
            {
                // get the source for the variable.
                IHistoryDataSource datasource = null;
                ServiceResult      error      = GetHistoryDataSource(serverContext, source, out datasource);

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

                // create a reader.
                reader = new HistoryDataReader(nodeToRead.NodeId, datasource);

                // start reading.
                reader.BeginReadRaw(
                    serverContext,
                    details,
                    timestampsToReturn,
                    nodeToRead.ParsedIndexRange,
                    nodeToRead.DataEncoding,
                    data.DataValues);
            }

            // continue reading data until done or max values reached.
            bool complete = reader.NextReadRaw(
                serverContext,
                timestampsToReturn,
                nodeToRead.ParsedIndexRange,
                nodeToRead.DataEncoding,
                data.DataValues);

            // save continuation point.
            if (!complete)
            {
                SaveDataReader(serverContext, reader);
                result.StatusCode = StatusCodes.GoodMoreData;
            }

            // return the dat.
            result.HistoryData = new ExtensionObject(data);

            return(result.StatusCode);
        }
        /// <summary>
        /// Invokes the Read service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="maxAge">The Maximum age of the value to be read in milliseconds.</param>
        /// <param name="timestampsToReturn">The type of timestamps to be returned for the requested Variables.</param>
        /// <param name="nodesToRead">The list of Nodes and their Attributes to read.</param>
        /// <param name="results">The list of returned Attribute values</param>
        /// <param name="diagnosticInfos">The diagnostic information for the results.</param>
        /// <returns>
        /// Returns a <see cref="ResponseHeader"/> object
        /// </returns>
        public override ResponseHeader Read(
            RequestHeader                requestHeader, 
            double                       maxAge, 
            TimestampsToReturn           timestampsToReturn, 
            ReadValueIdCollection        nodesToRead, 
            out DataValueCollection      results, 
            out DiagnosticInfoCollection diagnosticInfos)
        {
            OperationContext context = ValidateRequest(requestHeader, RequestType.Read);

            try
            {
                if (nodesToRead == null || nodesToRead.Count == 0)
                {
                    throw new ServiceResultException(StatusCodes.BadNothingToDo);
                }

                m_serverInternal.NodeManager.Read(
                    context,
                    maxAge,
                    timestampsToReturn,
                    nodesToRead,
                    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>
        /// Validates the nodes and reads the values from the underlying source.
        /// </summary>
        protected virtual void HistoryRead(
            ServerSystemContext context,
            HistoryReadDetails details, 
            TimestampsToReturn timestampsToReturn, 
            bool releaseContinuationPoints, 
            IList<HistoryReadValueId> nodesToRead, 
            IList<HistoryReadResult> results, 
            IList<ServiceResult> errors,
            List<NodeHandle> nodesToProcess,
            IDictionary<NodeId, NodeState> cache)
        {
            // check if continuation points are being released.
            if (releaseContinuationPoints)
            {
                HistoryReleaseContinuationPoints(
                    context,
                    nodesToRead,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }

            // check timestamps to return.
            if (timestampsToReturn < TimestampsToReturn.Source || timestampsToReturn > TimestampsToReturn.Neither)
            {
                throw new ServiceResultException(StatusCodes.BadTimestampsToReturnInvalid);
            }

            // handle raw data request.
            ReadRawModifiedDetails readRawModifiedDetails = details as ReadRawModifiedDetails;
            
            if (readRawModifiedDetails != null)
            {
                // at least one must be provided.
                if (readRawModifiedDetails.StartTime == DateTime.MinValue && readRawModifiedDetails.EndTime == DateTime.MinValue)
                {
                    throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                }

                // if one is null the num values must be provided.
                if (readRawModifiedDetails.StartTime == DateTime.MinValue || readRawModifiedDetails.EndTime == DateTime.MinValue)
                {
                    if (readRawModifiedDetails.NumValuesPerNode == 0)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                    }
                }

                HistoryReadRawModified(
                    context,
                    readRawModifiedDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }

            // handle processed data request.
            ReadProcessedDetails readProcessedDetails = details as ReadProcessedDetails;
            
            if (readProcessedDetails != null)
            {
                // check the list of aggregates.
                if (readProcessedDetails.AggregateType == null || readProcessedDetails.AggregateType.Count != nodesToRead.Count)
                {
                    throw new ServiceResultException(StatusCodes.BadAggregateListMismatch);
                }

                // check start/end time.
                if (readProcessedDetails.StartTime == DateTime.MinValue || readProcessedDetails.EndTime == DateTime.MinValue)
                {
                    throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                }

                HistoryReadProcessed(
                    context,
                    readProcessedDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }
            
            // handle raw data at time request.
            ReadAtTimeDetails readAtTimeDetails = details as ReadAtTimeDetails;
            
            if (readAtTimeDetails != null)
            {
                HistoryReadAtTime(
                    context,
                    readAtTimeDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }

            // handle read events request.
            ReadEventDetails readEventDetails = details as ReadEventDetails;

            if (readEventDetails != null)
            {
                // check start/end time and max values.
                if (readEventDetails.NumValuesPerNode == 0)
                {
                    if (readEventDetails.StartTime == DateTime.MinValue || readEventDetails.EndTime == DateTime.MinValue)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                    }
                }
                else
                {
                    if (readEventDetails.StartTime == DateTime.MinValue && readEventDetails.EndTime == DateTime.MinValue)
                    {
                        throw new ServiceResultException(StatusCodes.BadInvalidTimestampArgument);
                    }
                }

                // validate the event filter.
                EventFilter.Result result = readEventDetails.Filter.Validate(new FilterContext(m_server.NamespaceUris, m_server.TypeTree, context));

                if (ServiceResult.IsBad(result.Status))
                {
                    throw new ServiceResultException(result.Status);
                }

                // read the event history.
                HistoryReadEvents(
                    context,
                    readEventDetails,
                    timestampsToReturn,
                    nodesToRead,
                    results,
                    errors,
                    nodesToProcess,
                    cache);

                return;
            }
        }
        /// <summary>
        /// Creates a new set of monitored items for a set of variables.
        /// </summary>
        /// <remarks>
        /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
        /// </remarks>
        protected virtual ServiceResult CreateMonitoredItem(
            ServerSystemContext context,
            NodeHandle handle,
            uint subscriptionId,
            double publishingInterval,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest itemToCreate,
            ref long globalIdCounter,
            out MonitoringFilterResult filterResult,
            out IMonitoredItem monitoredItem)
        {
            filterResult = null;
            monitoredItem = null;

            // validate parameters.
            MonitoringParameters parameters = itemToCreate.RequestedParameters;

            // validate attribute.
            if (!Attributes.IsValid(handle.Node.NodeClass, itemToCreate.ItemToMonitor.AttributeId))
            {
                return StatusCodes.BadAttributeIdInvalid;
            }

            // check if the node is already being monitored.
            MonitoredNode monitoredNode = null;

            if (!m_monitoredNodes.TryGetValue(handle.Node.NodeId, out monitoredNode))
            {
                NodeState cachedNode = AddNodeToComponentCache(context, handle, handle.Node);
                m_monitoredNodes[handle.Node.NodeId] = monitoredNode = new MonitoredNode(this, cachedNode);
            }

            handle.Node = monitoredNode.Node;
            handle.MonitoredNode = monitoredNode;

            // create a globally unique identifier.
            uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);

            // determine the sampling interval.
            double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = publishingInterval;
            }

            // ensure minimum sampling interval is not exceeded.
            if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
            {
                BaseVariableState variable = handle.Node as BaseVariableState;

                if (variable != null && samplingInterval < variable.MinimumSamplingInterval)
                {
                    samplingInterval = variable.MinimumSamplingInterval;
                }
            }

            // put a large upper limit on sampling.
            if (samplingInterval == Double.MaxValue)
            {
                samplingInterval = 365 * 24 * 3600 * 1000.0;
            }

            // put an upper limit on queue size.
            uint queueSize = itemToCreate.RequestedParameters.QueueSize;

            if (queueSize > m_maxQueueSize)
            {
                queueSize = m_maxQueueSize;
            }

            // validate the monitoring filter.
            Range euRange = null;
            MonitoringFilter filterToUse = null;

            ServiceResult error = ValidateMonitoringFilter(
                context,
                handle,
                itemToCreate.ItemToMonitor.AttributeId,
                samplingInterval,
                queueSize,
                parameters.Filter,
                out filterToUse,
                out euRange,
                out filterResult);

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

            // create the item.
            MonitoredItem datachangeItem = new MonitoredItem(
                Server,
                this,
                handle,
                subscriptionId,
                monitoredItemId,
                context.OperationContext.Session,
                itemToCreate.ItemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                filterToUse,
                filterToUse,
                euRange,
                samplingInterval,
                queueSize,
                itemToCreate.RequestedParameters.DiscardOldest,
                0);

            // report the initial value.
            ReadInitialValue(context, handle, datachangeItem);

            // update monitored item list.
            monitoredItem = datachangeItem;

            // save the monitored item.
            m_monitoredItems.Add(monitoredItemId, datachangeItem);
            monitoredNode.Add(datachangeItem);

            // report change.
            OnMonitoredItemCreated(context, handle, datachangeItem);

            return error;
        }
        /// <summary>
        /// Reads the history for a single node which has already been validated.
        /// </summary>
        protected virtual ServiceResult HistoryRead(
            ISystemContext context, 
            NodeState           source,
            HistoryReadDetails  details, 
            TimestampsToReturn  timestampsToReturn, 
            bool                releaseContinuationPoints, 
            HistoryReadValueId  nodesToRead, 
            HistoryReadResult   result)
        {
            // check for variable.
            BaseVariableState variable = source as BaseVariableState;

            if (variable == null)
            {
                return StatusCodes.BadHistoryOperationUnsupported;
            }

            // check for access.
            lock (Lock)
            {
                if ((variable.AccessLevel & AccessLevels.HistoryRead) == 0)
                {
                    return StatusCodes.BadNotReadable;
                }
            }

            // handle read raw.
            ReadRawModifiedDetails readRawDetails = details as ReadRawModifiedDetails;

            if (readRawDetails != null)
            {
                return HistoryReadRaw(
                    context,
                    variable,
                    readRawDetails,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead,
                    result);
            }

            // handle read processed.
            ReadProcessedDetails readProcessedDetails = details as ReadProcessedDetails;

            if (readProcessedDetails != null)
            {
                return HistoryReadProcessed(
                    context,
                    variable,
                    readProcessedDetails,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead,
                    result);
            }

            // handle read processed.
            ReadAtTimeDetails readAtTimeDetails = details as ReadAtTimeDetails;

            if (readAtTimeDetails != null)
            {
                return HistoryReadAtTime(
                    context,
                    variable,
                    readAtTimeDetails,
                    timestampsToReturn,
                    releaseContinuationPoints,
                    nodesToRead,
                    result);
            }
 
            return StatusCodes.BadHistoryOperationUnsupported;
        }
 /// <summary>
 /// Reads the history for the variable value.
 /// </summary>
 protected virtual ServiceResult HistoryReadAtTime(
     ISystemContext context, 
     BaseVariableState      source,
     ReadAtTimeDetails      details, 
     TimestampsToReturn     timestampsToReturn, 
     bool                   releaseContinuationPoints, 
     HistoryReadValueId     nodeToRead, 
     HistoryReadResult      result)
 {
     return StatusCodes.BadHistoryOperationUnsupported;
 }
        /// <summary>
        /// Modifies the parameters for a set of monitored items.
        /// </summary>
        public virtual void ModifyMonitoredItems(
            OperationContext                  context, 
            TimestampsToReturn                timestampsToReturn, 
            IList<IMonitoredItem>             monitoredItems, 
            IList<MonitoredItemModifyRequest> itemsToModify, 
            IList<ServiceResult>              errors, 
            IList<MonitoringFilterResult>     filterResults)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            List<IMonitoredItem> modifiedItems = new List<IMonitoredItem>();

            lock (Lock)
            {
                for (int ii = 0; ii < monitoredItems.Count; ii++)
                {                    
                    MonitoredItemModifyRequest itemToModify = itemsToModify[ii];

                    // skip items that have already been processed.
                    if (itemToModify.Processed || monitoredItems[ii] == null)
                    {
                        continue;
                    }

                    // check handle.
                    NodeHandle handle = IsHandleInNamespace(monitoredItems[ii].ManagerHandle);

                    if (handle == null)
                    {
                        continue;
                    }

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

                    // modify the monitored item.
                    MonitoringFilterResult filterResult = null;

                    errors[ii] = ModifyMonitoredItem(
                        systemContext,
                        context.DiagnosticsMask,
                        timestampsToReturn,
                        monitoredItems[ii],
                        itemToModify,
                        handle,
                        out filterResult);

                    // save any filter error details.
                    filterResults[ii] = filterResult;

                    // save the modified item.
                    if (ServiceResult.IsGood(errors[ii]))
                    {
                        modifiedItems.Add(monitoredItems[ii]);
                    }
                }
            }

            // do any post processing.
            OnModifyMonitoredItemsComplete(systemContext, modifiedItems);
        }
        /// <summary>
        /// Creates a new set of monitored items for a set of variables.
        /// </summary>
        /// <remarks>
        /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
        /// </remarks>
        protected virtual ServiceResult CreateMonitoredItem(
            ISystemContext context,
            NodeState source,
            uint subscriptionId,
            double publishingInterval,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest itemToCreate,
            ref long globalIdCounter,
            out MonitoringFilterResult filterError,
            out IMonitoredItem monitoredItem)
        {
            filterError = null;
            monitoredItem = null;
            ServiceResult error = null;
            
            // read initial value.
            DataValue initialValue = new DataValue();

            initialValue.Value = null;
            initialValue.ServerTimestamp = DateTime.UtcNow;
            initialValue.SourceTimestamp = DateTime.MinValue;
            initialValue.StatusCode = StatusCodes.Good;

            error = source.ReadAttribute(
                context,
                itemToCreate.ItemToMonitor.AttributeId,
                itemToCreate.ItemToMonitor.ParsedIndexRange,
                itemToCreate.ItemToMonitor.DataEncoding,
                initialValue);

            if (ServiceResult.IsBad(error))
            {
                return error;
            }
            
            // validate parameters.
            MonitoringParameters parameters = itemToCreate.RequestedParameters;

            // validate the data change filter.
            DataChangeFilter filter = null;
            Range range = null;

            if (!ExtensionObject.IsNull(parameters.Filter))
            {
                error = ValidateDataChangeFilter(
                    context,
                    source,
                    itemToCreate.ItemToMonitor.AttributeId,
                    parameters.Filter,
                    out filter,
                    out range);

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

            // create monitored node.
            MonitoredNode monitoredNode = source.Handle as MonitoredNode;

            if (monitoredNode == null)
            {
                source.Handle = monitoredNode = new MonitoredNode(m_server, this, source);
            }

            // create a globally unique identifier.
            uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);

            // determine the sampling interval.
            double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = publishingInterval;
            }

            // check if the variable needs to be sampled.
            bool samplingRequired = false;

            if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value)
            {
                BaseVariableState variable = source as BaseVariableState;

                if (variable.MinimumSamplingInterval > 0)
                {
                    samplingInterval = CalculateSamplingInterval(variable, samplingInterval);
                    samplingRequired = true;
                }
            }

            // create the item.
            DataChangeMonitoredItem datachangeItem = monitoredNode.CreateDataChangeItem(
                context,
                monitoredItemId,
                itemToCreate.ItemToMonitor.AttributeId,
                itemToCreate.ItemToMonitor.ParsedIndexRange,
                itemToCreate.ItemToMonitor.DataEncoding,
                diagnosticsMasks,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                samplingInterval,
                itemToCreate.RequestedParameters.QueueSize,
                itemToCreate.RequestedParameters.DiscardOldest,
                filter,
                range,
                false);

            if (samplingRequired)
            {
                CreateSampledItem(samplingInterval, datachangeItem);
            }

            // report the initial value.
            datachangeItem.QueueValue(initialValue, null);

            // do any post processing.
            OnCreateMonitoredItem(context, itemToCreate, monitoredNode, datachangeItem);

            // update monitored item list.
            monitoredItem = datachangeItem;

            return ServiceResult.Good;
        }
        /// <summary>
        /// Creates a new data change monitored item.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="monitoredItemId">The unique identifier for the monitiored item.</param>
        /// <param name="attributeId">The attribute to monitor.</param>
        /// <param name="indexRange">The index range to use for array values.</param>
        /// <param name="dataEncoding">The data encoding to return for structured values.</param>
        /// <param name="diagnosticsMasks">The diagnostics masks to use.</param>
        /// <param name="timestampsToReturn">The timestamps to return.</param>
        /// <param name="monitoringMode">The initial monitoring mode.</param>
        /// <param name="clientHandle">The handle assigned by the client.</param>
        /// <param name="samplingInterval">The sampling interval.</param>
        /// <param name="queueSize">The queue size.</param>
        /// <param name="discardOldest">Whether to discard the oldest values when the queue overflows.</param>
        /// <param name="filter">The data change filter to use.</param>
        /// <param name="range">The range to use when evaluating a percentage deadband filter.</param>
        /// <param name="alwaysReportUpdates">Whether the monitored item should skip the check for a change in value.</param>
        /// <returns>The new monitored item.</returns>
        public DataChangeMonitoredItem CreateDataChangeItem(
            ISystemContext context,
            uint monitoredItemId,
            uint attributeId,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoringMode monitoringMode,
            uint clientHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            DataChangeFilter filter,
            Range range,
            bool alwaysReportUpdates)
        {
            DataChangeMonitoredItem monitoredItem = new DataChangeMonitoredItem(
                this,
                monitoredItemId,
                attributeId,
                indexRange,
                dataEncoding,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                samplingInterval,
                queueSize,
                discardOldest,
                filter,
                range,
                alwaysReportUpdates);

            if (m_monitoredItems == null)
            {
                m_monitoredItems = new List<DataChangeMonitoredItem>();
                m_node.OnStateChanged = OnNodeChange;
            }

            m_monitoredItems.Add(monitoredItem);

            return monitoredItem;
        }
        /// <summary>
        /// Modifies the parameters for a monitored item.
        /// </summary>
        protected virtual ServiceResult ModifyMonitoredItem(
            ISystemContext context,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            IMonitoredItem monitoredItem,
            MonitoredItemModifyRequest itemToModify,
            out MonitoringFilterResult filterError)
        {
            filterError = null;
            ServiceResult error = null;

            // check for valid handle.
            MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode;

            if (monitoredNode == null)
            {
                return ServiceResult.Good;
            }

            if (IsHandleInNamespace(monitoredNode.Node) == null)
            {
                return ServiceResult.Good;
            }

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

            // check for valid monitored item.
            DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem;

            // validate parameters.
            MonitoringParameters parameters = itemToModify.RequestedParameters;

            // validate the data change filter.
            DataChangeFilter filter = null;
            Range range = null;

            if (!ExtensionObject.IsNull(parameters.Filter))
            {
                error = ValidateDataChangeFilter(
                    context,
                    monitoredNode.Node,
                    datachangeItem.AttributeId,
                    parameters.Filter,
                    out filter,
                    out range);

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

            double previousSamplingInterval = datachangeItem.SamplingInterval;
            
            // check if the variable needs to be sampled.
            double samplingInterval = itemToModify.RequestedParameters.SamplingInterval;

            if (datachangeItem.AttributeId == Attributes.Value)
            {
                BaseVariableState variable = monitoredNode.Node as BaseVariableState;

                if (variable.MinimumSamplingInterval > 0)
                {
                    samplingInterval = CalculateSamplingInterval(variable, samplingInterval);
                }
            }

            // modify the monitored item parameters.
            error = datachangeItem.Modify(
                diagnosticsMasks,
                timestampsToReturn,
                itemToModify.RequestedParameters.ClientHandle,
                samplingInterval,
                itemToModify.RequestedParameters.QueueSize,
                itemToModify.RequestedParameters.DiscardOldest,
                filter,
                range);

            // do any post processing.
            OnModifyMonitoredItem(
                context, 
                itemToModify, 
                monitoredNode, 
                datachangeItem,
                previousSamplingInterval);

            return ServiceResult.Good;
        }
        /// <summary>
        /// Invokes the Read service.
        /// </summary>
        public virtual ResponseHeader Read(
            RequestHeader                requestHeader,
            double                       maxAge,
            TimestampsToReturn           timestampsToReturn,
            ReadValueIdCollection        nodesToRead,
            out DataValueCollection      results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
Esempio n. 51
0
        /// <summary>
        /// Reads the history of an HDA item annotations.
        /// </summary>
        private ServiceResult HistoryReadAnnotations(
            ServerSystemContext context,
            ComHdaClient client,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            HistoryReadValueId nodeToRead,
            HdaParsedNodeId parsedNodeId,
            HistoryReadResult result)
        {
            // create the request or load it from a continuation point.
            HdaHistoryReadAnnotationRequest request = null;

            if (nodeToRead.ContinuationPoint == null)
            {
                // create a new request.
                request = new HdaHistoryReadAnnotationRequest(parsedNodeId.RootId, details, nodeToRead);

                // fetch all of the data at once.
                result.StatusCode = client.ReadAnnotationHistory(request);
            }
            else
            {
                request = LoadContinuationPoint(context, nodeToRead.ContinuationPoint) as HdaHistoryReadAnnotationRequest;

                if (request == null)
                {
                    return StatusCodes.BadContinuationPointInvalid;
                }
            }

            // select a subset of the results.
            if (StatusCode.IsGood(result.StatusCode))
            {
                request.Results = new DataValueCollection();
                request.GetHistoryResults(context, nodeToRead, request.Results);
            }

            // fill in the results.
            if (request.Results != null)
            {
                HistoryData data = new HistoryData();
                data.DataValues = request.Results;
                result.HistoryData = new ExtensionObject(data);
            }

            // create a new continuation point.
            if (!request.Completed)
            {
                result.ContinuationPoint = SaveContinuationPoint(context, request);
            }

            return result.StatusCode;
        }
Esempio n. 52
0
		/// <summary>
		/// Adds monitored items to a subscription.
		/// </summary>
		public void CreateMonitoredItems(
            OperationContext                        context,
            TimestampsToReturn                      timestampsToReturn,
            MonitoredItemCreateRequestCollection    itemsToCreate, 
            out MonitoredItemCreateResultCollection results, 
            out DiagnosticInfoCollection            diagnosticInfos)
        {
            if (context == null)       throw new ArgumentNullException("context");
            if (itemsToCreate == null) throw new ArgumentNullException("itemsToCreate");
            
            int count = itemsToCreate.Count;
            
            lock (m_lock)
            {
                // check session.
                VerifySession(context);

                // clear lifetime counter.
                ResetLifetimeCount();
            }
             
            // create the monitored items.
            List<IMonitoredItem> monitoredItems = new List<IMonitoredItem>(count);
            List<ServiceResult> errors = new List<ServiceResult>(count);
            List<MonitoringFilterResult> filterResults = new List<MonitoringFilterResult>(count);

            for (int ii = 0; ii < count; ii++)
            {
                monitoredItems.Add(null);
                errors.Add(null);
                filterResults.Add(null);
            }
            
            m_server.NodeManager.CreateMonitoredItems(
                context,
                this.m_id,
                m_publishingInterval,
                timestampsToReturn,
                itemsToCreate,
                errors,
                filterResults,
                monitoredItems);
                
            // allocate results.
            bool diagnosticsExist = false;
            results = new MonitoredItemCreateResultCollection(count);
            diagnosticInfos = null;

            if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
            {
                diagnosticInfos = new DiagnosticInfoCollection(count);
            }

            lock (m_lock)
            {
                // check session again after CreateMonitoredItems.
                VerifySession(context);

                for (int ii = 0; ii < errors.Count; ii++)
                {
                    // update results.
                    MonitoredItemCreateResult result = null;
                    
                    if (ServiceResult.IsBad(errors[ii]))
                    {
                        result = new MonitoredItemCreateResult();
                        result.StatusCode = errors[ii].Code;

                        if (filterResults[ii] != null)
                        {
                            result.FilterResult = new ExtensionObject(filterResults[ii]);
                        }
                    }
                    else
                    {
                        IMonitoredItem monitoredItem = monitoredItems[ii];

                        if (monitoredItem != null)
                        {
                            monitoredItem.SubscriptionCallback = this;
                            
                            LinkedListNode<IMonitoredItem> node = m_itemsToCheck.AddLast(monitoredItem);
                            m_monitoredItems.Add(monitoredItem.Id, node);

                            errors[ii] = monitoredItem.GetCreateResult(out result);

                            // update sampling interval diagnostics.
                            AddItemToSamplingInterval(result.RevisedSamplingInterval, itemsToCreate[ii].MonitoringMode);
                        }
                    }                   

                    results.Add(result);

                    // update diagnostics.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        DiagnosticInfo diagnosticInfo = null;
                        
                        if (errors[ii] != null && errors[ii].Code != StatusCodes.Good)
                        {
                            diagnosticInfo = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
                            diagnosticsExist = true;
                        }

                        diagnosticInfos.Add(diagnosticInfo);
                    }
                }

                // 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 CREATED");
            }
        }
Esempio n. 53
0
        /// <summary>
        /// Reads raw history data.
        /// </summary>
        protected override void HistoryReadRawModified(
            ServerSystemContext context,
            ReadRawModifiedDetails details,
            TimestampsToReturn timestampsToReturn,
            IList<HistoryReadValueId> nodesToRead,
            IList<HistoryReadResult> results,
            IList<ServiceResult> errors,
            List<NodeHandle> nodesToProcess,
            IDictionary<NodeId, NodeState> cache)
        {
            ComHdaClientManager system = (ComHdaClientManager)this.SystemContext.SystemHandle;
            ComHdaClient client = (ComHdaClient)system.SelectClient((ServerSystemContext)SystemContext, false);

            for (int ii = 0; ii < nodesToProcess.Count; ii++)
            {
                NodeHandle handle = nodesToProcess[ii];
                HistoryReadValueId nodeToRead = nodesToRead[handle.Index];
                HistoryReadResult result = results[handle.Index];

                // check if the node id has been parsed.
                HdaParsedNodeId parsedNodeId = handle.ParsedNodeId as HdaParsedNodeId;

                if (parsedNodeId == null)
                {
                    errors[handle.Index] = StatusCodes.BadNodeIdInvalid;
                    continue;
                }

                // read the history of an item.
                if (parsedNodeId.RootType == HdaModelUtils.HdaItem)
                {
                    errors[handle.Index] = HistoryReadItem(
                        context,
                        client,
                        details,
                        timestampsToReturn,
                        nodeToRead,
                        parsedNodeId,
                        result);

                    continue;
                }

                // read the history of an attribute.
                if (parsedNodeId.RootType == HdaModelUtils.HdaItemAttribute)
                {
                    errors[handle.Index] = HistoryReadAttribute(
                        context,
                        client,
                        details,
                        timestampsToReturn,
                        nodeToRead,
                        parsedNodeId,
                        result);

                    continue;
                }

                // read the annotations of an item.
                if (parsedNodeId.RootType == HdaModelUtils.HdaItemAnnotations)
                {
                    errors[handle.Index] = HistoryReadAnnotations(
                        context,
                        client,
                        details,
                        timestampsToReturn,
                        nodeToRead,
                        parsedNodeId,
                        result);

                    continue;
                }

                errors[handle.Index] = StatusCodes.BadHistoryOperationUnsupported;
            }
        }
        /// <summary>
        /// Invokes the ModifyMonitoredItems service.
        /// </summary>
        public virtual ResponseHeader ModifyMonitoredItems(
            RequestHeader                           requestHeader,
            uint                                    subscriptionId,
            TimestampsToReturn                      timestampsToReturn,
            MonitoredItemModifyRequestCollection    itemsToModify,
            out MonitoredItemModifyResultCollection results,
            out DiagnosticInfoCollection            diagnosticInfos)
        {
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
        /// <summary>
        /// Creates a new set of monitored items for a set of variables.
        /// </summary>
        /// <remarks>
        /// This method only handles data change subscriptions. Event subscriptions are created by the SDK.
        /// </remarks>
        protected override ServiceResult CreateMonitoredItem(
            ISystemContext context,
            NodeState source,
            uint subscriptionId,
            double publishingInterval,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoredItemCreateRequest itemToCreate,
            ref long globalIdCounter,
            out MonitoringFilterResult filterError,
            out IMonitoredItem monitoredItem)
        {
            filterError   = null;
            monitoredItem = null;


            // use default behavoir for non-tag sources.
            if (!(source is MemoryTagState tag))
            {
                return(base.CreateMonitoredItem(
                           context,
                           source,
                           subscriptionId,
                           publishingInterval,
                           diagnosticsMasks,
                           timestampsToReturn,
                           itemToCreate,
                           ref globalIdCounter,
                           out filterError,
                           out monitoredItem));
            }

            // validate parameters.
            var parameters = itemToCreate.RequestedParameters;

            // no filters supported at this time.
            var filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter);

            if (filter != null)
            {
                return(StatusCodes.BadFilterNotAllowed);
            }

            // index range not supported.
            if (itemToCreate.ItemToMonitor.ParsedIndexRange != NumericRange.Empty)
            {
                return(StatusCodes.BadIndexRangeInvalid);
            }

            // data encoding not supported.
            if (!QualifiedName.IsNull(itemToCreate.ItemToMonitor.DataEncoding))
            {
                return(StatusCodes.BadDataEncodingInvalid);
            }

            // read initial value.
            var initialValue = new DataValue {
                Value           = null,
                ServerTimestamp = DateTime.UtcNow,
                SourceTimestamp = DateTime.MinValue,
                StatusCode      = StatusCodes.Good
            };

            var error = source.ReadAttribute(
                context,
                itemToCreate.ItemToMonitor.AttributeId,
                itemToCreate.ItemToMonitor.ParsedIndexRange,
                itemToCreate.ItemToMonitor.DataEncoding,
                initialValue);

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

            // get the monitored node for the containing buffer.

            if (!(tag.Parent is MemoryBufferState buffer))
            {
                return(StatusCodes.BadInternalError);
            }

            // create a globally unique identifier.
            var monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter);

            // determine the sampling interval.
            var samplingInterval = itemToCreate.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = publishingInterval;
            }

            // create the item.
            var datachangeItem = buffer.CreateDataChangeItem(
                context as ServerSystemContext,
                tag,
                monitoredItemId,
                itemToCreate.ItemToMonitor,
                diagnosticsMasks,
                timestampsToReturn,
                itemToCreate.MonitoringMode,
                itemToCreate.RequestedParameters.ClientHandle,
                samplingInterval);

            /*
             * // create the item.
             * MemoryBufferMonitoredItem datachangeItem = buffer.CreateDataChangeItem(
             *  context,
             *  tag,
             *  monitoredItemId,
             *  itemToCreate.ItemToMonitor.AttributeId,
             *  diagnosticsMasks,
             *  timestampsToReturn,
             *  itemToCreate.MonitoringMode,
             *  itemToCreate.RequestedParameters.ClientHandle,
             *  samplingInterval);
             */

            // report the initial value.
            datachangeItem.QueueValue(initialValue, null);

            // update monitored item list.
            monitoredItem = datachangeItem;

            return(ServiceResult.Good);
        }
        /// <summary>
        /// Modifies the parameters for a monitored item.
        /// </summary>
        protected virtual ServiceResult ModifyMonitoredItem(
            ServerSystemContext context,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            IMonitoredItem monitoredItem,
            MonitoredItemModifyRequest itemToModify,
            NodeHandle handle,
            out MonitoringFilterResult filterResult)
        {
            filterResult = null;
            
            // check for valid monitored item.
            MonitoredItem datachangeItem = monitoredItem as MonitoredItem;

            // validate parameters.
            MonitoringParameters parameters = itemToModify.RequestedParameters;

            double previousSamplingInterval = datachangeItem.SamplingInterval;
            
            // check if the variable needs to be sampled.
            double samplingInterval = itemToModify.RequestedParameters.SamplingInterval;

            if (samplingInterval < 0)
            {
                samplingInterval = previousSamplingInterval;
            }

            // ensure minimum sampling interval is not exceeded.
            if (datachangeItem.AttributeId == Attributes.Value)
            {
                BaseVariableState variable = handle.Node as BaseVariableState;

                if (variable != null && samplingInterval < variable.MinimumSamplingInterval)
                {
                    samplingInterval = variable.MinimumSamplingInterval;
                }
            }

            // put a large upper limit on sampling.
            if (samplingInterval == Double.MaxValue)
            {
                samplingInterval = 365 * 24 * 3600 * 1000.0;
            }

            // put an upper limit on queue size.
            uint queueSize = itemToModify.RequestedParameters.QueueSize;

            if (queueSize > m_maxQueueSize)
            {
                queueSize = m_maxQueueSize;
            }

            // validate the monitoring filter.
            Range euRange = null;
            MonitoringFilter filterToUse = null;

            ServiceResult error = ValidateMonitoringFilter(
                context,
                handle,
                datachangeItem.AttributeId,
                samplingInterval,
                queueSize,
                parameters.Filter,
                out filterToUse,
                out euRange,
                out filterResult);

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

            // modify the monitored item parameters.
            error = datachangeItem.ModifyAttributes(
                diagnosticsMasks,
                timestampsToReturn,
                itemToModify.RequestedParameters.ClientHandle,
                filterToUse,
                filterToUse,
                euRange,
                samplingInterval,
                queueSize,
                itemToModify.RequestedParameters.DiscardOldest);
            
            // report change.
            if (ServiceResult.IsGood(error))
            {
                OnMonitoredItemModified(context, handle, datachangeItem);
            }

            return error;
        }
Esempio n. 57
0
		/// <summary>
		/// Modifies monitored items in a subscription.
		/// </summary>
		public void ModifyMonitoredItems(
			OperationContext                        context,
			TimestampsToReturn                      timestampsToReturn,
			MonitoredItemModifyRequestCollection    itemsToModify,
			out MonitoredItemModifyResultCollection results,
            out DiagnosticInfoCollection            diagnosticInfos)
        {
            if (context == null)       throw new ArgumentNullException("context");
            if (itemsToModify == null) throw new ArgumentNullException("itemsToModify");

            int count = itemsToModify.Count;

            // allocate results.
            bool diagnosticsExist = false;
            results = new MonitoredItemModifyResultCollection(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);
            List<MonitoringFilterResult> filterResults = new List<MonitoringFilterResult>(count);
            double[] originalSamplingIntervals = new double[count];

            bool validItems = false;

            lock (m_lock)
            {
                // check session.
                VerifySession(context);

                // clear lifetime counter.
                ResetLifetimeCount();

                for (int ii = 0; ii < count; ii++)
                {
                    filterResults.Add(null);

                    LinkedListNode<IMonitoredItem> node = null;

                    if (!m_monitoredItems.TryGetValue(itemsToModify[ii].MonitoredItemId, 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);
                    originalSamplingIntervals[ii] = monitoredItem.SamplingInterval;

                    errors.Add(null);
                    validItems = true;

                    // update diagnostics.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfos.Add(null);
                    }
                }
            }
                
             // update items.
            if (validItems)
            {
                m_server.NodeManager.ModifyMonitoredItems(
                    context,
                    timestampsToReturn,
                    monitoredItems,
                    itemsToModify,
                    errors,
                    filterResults);
            }
                   
            lock (m_lock)
            {             
                // create results.
                for (int ii = 0; ii < errors.Count; ii++)
                {
                    ServiceResult error = errors[ii];

                    MonitoredItemModifyResult result = null;

                    if (ServiceResult.IsGood(error))
                    {
                        error = monitoredItems[ii].GetModifyResult(out result);
                    }

                    if (result == null)
                    {
                        result = new MonitoredItemModifyResult();
                    }
                    
                    if (error == null)
                    {
                        result.StatusCode = StatusCodes.Good;
                    }
                    else
                    {
                        result.StatusCode = error.StatusCode;
                    }

                    // update diagnostics.
                    if (ServiceResult.IsGood(error))
                    {
                        ModifyItemSamplingInterval(originalSamplingIntervals[ii], result.RevisedSamplingInterval, monitoredItems[ii].MonitoringMode);
                    }

                    if (filterResults[ii] != null)
                    {
                        result.FilterResult = new ExtensionObject(filterResults[ii]);
                    }

                    results.Add(result);

                    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();
                }
                
                // TraceState("ITEMS MODIFIED");
            }
        }
Esempio n. 58
0
        /// <summary>
        /// Creates a new data change monitored item.
        /// </summary>
        public MemoryBufferMonitoredItem CreateDataChangeItem(
            ServerSystemContext context,
            MemoryTagState      tag,
            uint                subscriptionId,
            uint                monitoredItemId,
            ReadValueId         itemToMonitor,
            DiagnosticsMasks    diagnosticsMasks,
            TimestampsToReturn  timestampsToReturn,
            MonitoringMode      monitoringMode,
            uint                clientHandle,
            double              samplingInterval)

            /*
            ISystemContext context,
            MemoryTagState tag,
            uint monitoredItemId,
            uint attributeId,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoringMode monitoringMode,
            uint clientHandle,
            double samplingInterval)*/
        {
            lock (m_dataLock)
            {
                MemoryBufferMonitoredItem monitoredItem = new MemoryBufferMonitoredItem(
                    m_server,
                    m_nodeManager,
                    this,
                    tag.Offset,
                    0,
                    monitoredItemId,
                    context.OperationContext.Session,
                    itemToMonitor,
                    diagnosticsMasks,
                    timestampsToReturn,
                    monitoringMode,
                    clientHandle,
                    null,
                    null,
                    null,
                    samplingInterval,
                    0,
                    false,
                    0);

                /*
                MemoryBufferMonitoredItem monitoredItem = new MemoryBufferMonitoredItem(
                    this,
                    monitoredItemId,
                    tag.Offset,
                    attributeId,
                    diagnosticsMasks,
                    timestampsToReturn,
                    monitoringMode,
                    clientHandle,
                    samplingInterval);
                */

                if (itemToMonitor.AttributeId != Attributes.Value)
                {
                    m_nonValueMonitoredItems.Add(monitoredItem.Id, monitoredItem);
                    return monitoredItem;
                }

                int elementCount = (int)(SizeInBytes.Value / ElementSize);

                if (m_monitoringTable == null)
                {
                    m_monitoringTable = new MemoryBufferMonitoredItem[elementCount][];
                    m_scanTimer = new Timer(DoScan, null, 100, 100);
                }

                int elementOffet = (int)(tag.Offset / ElementSize);

                MemoryBufferMonitoredItem[] monitoredItems = m_monitoringTable[elementOffet];

                if (monitoredItems == null)
                {
                    monitoredItems = new MemoryBufferMonitoredItem[1];
                }
                else
                {
                    monitoredItems = new MemoryBufferMonitoredItem[monitoredItems.Length + 1];
                    m_monitoringTable[elementOffet].CopyTo(monitoredItems, 0);
                }

                monitoredItems[monitoredItems.Length - 1] = monitoredItem;
                m_monitoringTable[elementOffet] = monitoredItems;
                m_itemCount++;

                return monitoredItem;
            }
        }
		/// <summary>
		/// Modifies the attributes for monitored item.
		/// </summary>
		public ServiceResult ModifyAttributes(
            DiagnosticsMasks   diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            uint               clientHandle,
            MonitoringFilter   originalFilter,
            MonitoringFilter   filterToUse,
            Range              range,
            double             samplingInterval,
            uint               queueSize,
            bool               discardOldest)
        {
            lock (m_lock)
			{
                m_diagnosticsMasks   = diagnosticsMasks;
                m_timestampsToReturn = timestampsToReturn;
                m_clientHandle       = clientHandle;
                m_discardOldest      = discardOldest;

                m_originalFilter = originalFilter;
                m_filterToUse    = filterToUse;
                                    
                if (range != null)
                {
                    m_range = range.High - range.Low;
                }

                SetSamplingInterval(samplingInterval);
                m_queueSize = queueSize;

                // check if aggregate filter has been updated.
                ServerAggregateFilter aggregateFilter = filterToUse as ServerAggregateFilter;

                if (filterToUse is ServerAggregateFilter)
                {
                    ServerAggregateFilter existingFilter = filterToUse as ServerAggregateFilter;

                    bool match = existingFilter != null;

                    if (match) if (existingFilter.AggregateType != aggregateFilter.AggregateType) match = false;
                    if (match) if (existingFilter.ProcessingInterval != aggregateFilter.ProcessingInterval) match = false;
                    if (match) if (existingFilter.StartTime != aggregateFilter.StartTime) match = false;
                    if (match) if (!existingFilter.AggregateConfiguration.IsEqual(aggregateFilter.AggregateConfiguration)) match = false;

                    if (!match)
                    {
                        m_calculator = m_server.AggregateManager.CreateCalculator(
                            aggregateFilter.AggregateType,
                            aggregateFilter.StartTime,
                            DateTime.MaxValue,
                            aggregateFilter.ProcessingInterval,
                            aggregateFilter.Stepped,
                            aggregateFilter.AggregateConfiguration);
                    }
                }

                // report change to item state.
                ServerUtils.ReportModifyMonitoredItem(
                    m_nodeId,
                    m_id,
                    m_samplingInterval,
                    m_queueSize,
                    m_discardOldest,
                    m_filterToUse,
                    m_monitoringMode);

                InitializeQueue();

                return null;
            }
        }
Esempio n. 60
0
        /// <summary>
        /// Verifies that the timestamps match the requested filter.
        /// </summary>
        protected bool VerifyTimestamps(
            Node node, 
            uint attributeId,
            TimestampsToReturn timestampsToReturn, 
            DataValue value)
        {
            // check server timestamp.
            if (timestampsToReturn != TimestampsToReturn.Server && timestampsToReturn != TimestampsToReturn.Both)
            {
                if (value.ServerTimestamp != DateTime.MinValue || value.ServerPicoseconds != 0)
                {                    
                    Log(
                        "Unexpected ServerTimestamp returned during read for Node '{0}'. NodeId = {1}, Attribute = {2}, Timestamp = {3}, Picoseconds = {4}",
                        node,
                        node.NodeId,
                        Attributes.GetBrowseName(attributeId),
                        value.ServerTimestamp,
                        value.ServerPicoseconds);

                    return false;
                }
            }

            if (timestampsToReturn == TimestampsToReturn.Server || timestampsToReturn == TimestampsToReturn.Both)
            {
                if (value.ServerTimestamp.AddHours(1) < DateTime.UtcNow || DateTime.UtcNow.AddHours(1) < value.ServerTimestamp)
                {                    
                    Log(
                        "Valid ServerTimestamp not returned during read for Node '{0}'. NodeId = {1}, Attribute = {2}, Timestamp = {3}, Picoseconds = {4}",
                        node,
                        node.NodeId,
                        Attributes.GetBrowseName(attributeId),
                        value.ServerTimestamp,
                        value.ServerPicoseconds);

                    return false;
                }
            }
            
            // check source timestamp.
            if (timestampsToReturn != TimestampsToReturn.Source && timestampsToReturn != TimestampsToReturn.Both)
            {
                if (value.SourceTimestamp != DateTime.MinValue || value.SourcePicoseconds != 0)
                {                    
                    Log(
                        "Unexpected SourceTimestamp returned during read for Node '{0}'. NodeId = {1}, Attribute = {2}, Timestamp = {3}, Picoseconds = {4}",
                        node,
                        node.NodeId,
                        Attributes.GetBrowseName(attributeId),
                        value.SourceTimestamp,
                        value.ServerPicoseconds);

                    return false;
                }
            }

            // check non-value attribute source timestamp.
            if (attributeId != Attributes.Value)
            {
                if (value.SourceTimestamp != DateTime.MinValue || value.SourcePicoseconds != 0)
                {                    
                    Log(
                        "Unexpected SourceTimestamp returned during non-value attribute for Node '{0}'. NodeId = {1}, Attribute = {2}, Timestamp = {3}, Picoseconds = {4}",
                        node,
                        node.NodeId,
                        Attributes.GetBrowseName(attributeId),
                        value.SourceTimestamp,
                        value.ServerPicoseconds);

                    return false;
                }
            }
            else if (StatusCode.IsGood(value.StatusCode))
            {
                if (timestampsToReturn == TimestampsToReturn.Source || timestampsToReturn == TimestampsToReturn.Both)
                {
                    if (value.SourceTimestamp.AddYears(10) < DateTime.UtcNow || DateTime.UtcNow.AddHours(1) < value.SourceTimestamp)
                    {                    
                        Log(
                            "Valid SourceTimestamp not returned during read for Node '{0}'. NodeId = {1}, Attribute = {2}, Timestamp = {3}, Picoseconds = {4}",
                            node,
                            node.NodeId,
                            Attributes.GetBrowseName(attributeId),
                            value.SourceTimestamp,
                            value.SourcePicoseconds);

                        return false;
                    }
                }
            }

            return true;
        }