Beispiel #1
0
        /// <summary>
        /// Updates the base event.
        /// </summary>
        private void UpdateBaseEvent(BaseEventState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            BinaryEncoder encoder = new BinaryEncoder(ServiceMessageContext.GlobalContext);

            encoder.WriteString(null, e.szSource);
            encoder.WriteString(null, e.szConditionName);
            encoder.WriteInt32(null, e.ftActiveTime.dwHighDateTime);
            encoder.WriteInt32(null, e.ftActiveTime.dwLowDateTime);
            encoder.WriteInt32(null, e.dwCookie);

            byte[]        eventId     = encoder.CloseAndReturnBuffer();
            NodeId        eventTypeId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, e.szConditionName, m_namespaceIndex);
            NodeId        sourceNode  = AeModelUtils.ConstructIdForSource(e.szSource, null, m_namespaceIndex);
            string        sourceName  = e.szSource;
            DateTime      time        = ComUtils.GetDateTime(e.ftTime);
            DateTime      receiveTime = DateTime.UtcNow;
            LocalizedText message     = e.szMessage;
            ushort        severity    = (ushort)e.dwSeverity;

            instance.TypeDefinitionId = eventTypeId;
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EventId, eventId, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EventType, eventTypeId, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.SourceNode, sourceNode, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.SourceName, sourceName, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Time, time, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ReceiveTime, receiveTime, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Message, message, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Severity, severity, false);
        }
Beispiel #2
0
 /// <summary>
 /// Updates the audit event.
 /// </summary>
 private void UpdateAuditEvent(AuditEventState instance, EventType eventType, ONEVENTSTRUCT e)
 {
     instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ActionTimeStamp, instance.Time.Value, false);
     instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Status, true, false);
     instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ServerId, m_defaultContext.NamespaceUris.GetString(m_namespaceIndex), false);
     instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ClientUserId, e.szActorID, false);
 }
        /// <summary>
        /// Initializes a COM-patible ONEVENTSTRUCT ready to be sent to subscribing clients
        /// </summary>
        /// <param name="oes"></param>
        /// <param name="pOnEventClass"></param>
        private void CopyToOnEventStruct(ref ONEVENTSTRUCT oes, OnEventClass pOnEventClass)
        {
            try
            {
                oes = pOnEventClass.InternalOES;

                ReturnedAttributeList attrIds;
                if (m_ReturnedAttributes.TryGetValue(oes.dwEventCategory, out attrIds) == true)
                {
                    int      retAttrCount = attrIds.Count;
                    int      i            = 0;
                    object[] attrVals     = new object[retAttrCount];

                    foreach (int attrId in attrIds)
                    {
                        attrVals[i++] = pOnEventClass.EventAttributes[attrId];
                    }

                    oes.dwNumEventAttrs  = retAttrCount;
                    oes.pEventAttributes = ComUtils.GetVARIANTs(attrVals, false);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error in CopyToOnEventStruct");
            }
        }
Beispiel #4
0
        internal static EventNotification GetEventNotification(ONEVENTSTRUCT input)
        {
            EventNotification eventNotification = new EventNotification();

            eventNotification.SourceID         = input.szSource;
            eventNotification.Time             = OpcCom.Interop.GetFILETIME(Convert(input.ftTime));
            eventNotification.Severity         = input.dwSeverity;
            eventNotification.Message          = input.szMessage;
            eventNotification.EventType        = (EventType)input.dwEventType;
            eventNotification.EventCategory    = input.dwEventCategory;
            eventNotification.ChangeMask       = input.wChangeMask;
            eventNotification.NewState         = input.wNewState;
            eventNotification.Quality          = new Quality(input.wQuality);
            eventNotification.ConditionName    = input.szConditionName;
            eventNotification.SubConditionName = input.szSubconditionName;
            eventNotification.AckRequired      = (input.bAckRequired != 0);
            eventNotification.ActiveTime       = OpcCom.Interop.GetFILETIME(Convert(input.ftActiveTime));
            eventNotification.Cookie           = input.dwCookie;
            eventNotification.ActorID          = input.szActorID;
            object[] vARIANTs = OpcCom.Interop.GetVARIANTs(ref input.pEventAttributes, input.dwNumEventAttrs, deallocate: false);
            eventNotification.SetAttributes(vARIANTs);
            return(eventNotification);
        }
        /// <summary>
        /// Clears the refresh related state from the subscription and generates a callback
        /// where bRefresh==true and bLastRefresh==true
        /// </summary>
        private void SendCancelRefresh()
        {
            lock (m_csData)
            {
                m_RefreshQ.Clear();
                m_bCancelRefresh = false;
                m_RefreshID      = 0;
            }

            // Create an empty event -- dwCount will be set to zero anyway
            ONEVENTSTRUCT[] emptyEvent = new ONEVENTSTRUCT[1];
            CopyToOnEventStruct(ref emptyEvent[0], new OnEventClass(null, null, new OPCCondition()));

            try
            {
                lock (m_lock)
                {
                    object callback = GetCallback(typeof(IOPCEventSink).GUID);

                    if (callback == null)
                    {
                        return;
                    }

                    ((IOPCEventSink)callback).OnEvent(m_hClientSubscription, 1, 1, 0, emptyEvent);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error in OnEvent callback.");
            }
            finally
            {
                Marshal.FreeCoTaskMem(emptyEvent[0].pEventAttributes);
            }
        }
Beispiel #6
0
        internal static EventNotification GetEventNotification(ONEVENTSTRUCT input)
        {
            EventNotification notification = new EventNotification {
                SourceID         = input.szSource,
                Time             = OpcCom.Interop.GetFILETIME(Convert(input.ftTime)),
                Severity         = input.dwSeverity,
                Message          = input.szMessage,
                EventType        = (EventType)input.dwEventType,
                EventCategory    = input.dwEventCategory,
                ChangeMask       = input.wChangeMask,
                NewState         = input.wNewState,
                Quality          = new Quality(input.wQuality),
                ConditionName    = input.szConditionName,
                SubConditionName = input.szSubconditionName,
                AckRequired      = input.bAckRequired != 0,
                ActiveTime       = OpcCom.Interop.GetFILETIME(Convert(input.ftActiveTime)),
                Cookie           = input.dwCookie,
                ActorID          = input.szActorID
            };

            object[] attributes = OpcCom.Interop.GetVARIANTs(ref input.pEventAttributes, input.dwNumEventAttrs, false);
            notification.SetAttributes(attributes);
            return(notification);
        }
Beispiel #7
0
 BaseEventState ConstructEvent(ONEVENTSTRUCT e)
 {
     return(null);
 }
Beispiel #8
0
        /// <summary>
        /// Updates the non-exclusive limit event.
        /// </summary>
        private void UpdateNonExclusiveLimitAlarm(NonExclusiveLimitAlarmState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            bool active = (e.wNewState & Constants.CONDITION_ACTIVE) != 0;
            TwoStateVariableState state = null;

            if (AeTypeCache.IsKnownName(e.szConditionName, "HI HI"))
            {
                instance.HighHighState            = state = new TwoStateVariableState(instance);
                instance.HighHighState.BrowseName = Opc.Ua.BrowseNames.HighHighState;
            }

            else if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI") || AeTypeCache.IsKnownName(e.szSubconditionName, "DV HI"))
            {
                instance.HighState            = state = new TwoStateVariableState(instance);
                instance.HighState.BrowseName = Opc.Ua.BrowseNames.HighState;
            }

            else if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO") || AeTypeCache.IsKnownName(e.szSubconditionName, "DV LO"))
            {
                instance.LowState            = state = new TwoStateVariableState(instance);
                instance.LowState.BrowseName = Opc.Ua.BrowseNames.LowState;
            }

            else if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO LO"))
            {
                instance.LowLowState            = state = new TwoStateVariableState(instance);
                instance.LowLowState.BrowseName = Opc.Ua.BrowseNames.LowLowState;
            }

            if (state != null)
            {
                state.Value = new LocalizedText((active) ? ConditionStateNames.Active : ConditionStateNames.Inactive);
                state.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, active, false);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Updates the exclusive limit alarm event.
        /// </summary>
        private void UpdateExclusiveLimitAlarm(ExclusiveLimitAlarmState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            NodeId state = null;
            string text  = null;

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI HI"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_HighHigh;
                text  = ConditionStateNames.HighHighActive;
            }

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_High;
                text  = ConditionStateNames.HighActive;
            }

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_Low;
                text  = ConditionStateNames.LowActive;
            }

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO LO"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_LowLow;
                text  = ConditionStateNames.LowLowActive;
            }

            instance.LimitState                         = new ExclusiveLimitStateMachineState(instance);
            instance.LimitState.BrowseName              = Opc.Ua.BrowseNames.LimitState;
            instance.LimitState.CurrentState            = new FiniteStateVariableState(instance.LimitState);
            instance.LimitState.CurrentState.BrowseName = Opc.Ua.BrowseNames.CurrentState;
            instance.LimitState.CurrentState.Value      = text;

            instance.LimitState.CurrentState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, state, false);
        }
Beispiel #10
0
        /// <summary>
        /// Updates the condition event.
        /// </summary>
        private void UpdateAlarm(AlarmConditionState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            instance.NodeId = AeParsedNodeId.ConstructIdForCondition(e.szSource, e.dwEventCategory, e.szConditionName, m_namespaceIndex);

            // find the condition class.
            NodeId           classId            = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, null, m_namespaceIndex);
            AeEventTypeState conditionClassType = m_cache.FindType(m_defaultContext, classId);

            if (conditionClassType != null)
            {
                instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassId, classId, false);
                instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassName, conditionClassType.EventType.Description, false);
            }
            else
            {
                instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassId, Opc.Ua.ObjectTypeIds.BaseConditionClassType, false);
                instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassName, "BaseConditionClass", false);
            }

            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionName, e.szConditionName, false);;
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ClientUserId, e.szActorID, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Quality, ComUtils.GetQualityCode(e.wQuality), false);

            bool acknowledged = (e.wNewState & Constants.CONDITION_ACKED) != 0;
            bool active       = (e.wNewState & Constants.CONDITION_ACTIVE) != 0;
            bool enabled      = (e.wNewState & Constants.CONDITION_ENABLED) != 0;
            bool retain       = enabled & (active || !acknowledged);

            LocalizedText effectiveDisplayName = ConditionStateNames.Inactive;

            if (!enabled)
            {
                effectiveDisplayName = ConditionStateNames.Disabled;
            }
            else if (!acknowledged)
            {
                effectiveDisplayName = ConditionStateNames.Unacknowledged;
            }
            else if (active)
            {
                effectiveDisplayName = ConditionStateNames.Active;
            }

            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Retain, true, false);

            instance.EnabledState            = new TwoStateVariableState(instance);
            instance.EnabledState.BrowseName = Opc.Ua.BrowseNames.EnabledState;
            instance.EnabledState.Value      = new LocalizedText((enabled) ? ConditionStateNames.Enabled : ConditionStateNames.Disabled);
            instance.EnabledState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, enabled, false);
            instance.EnabledState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EffectiveDisplayName, effectiveDisplayName, false);

            instance.AckedState            = new TwoStateVariableState(instance);
            instance.AckedState.BrowseName = Opc.Ua.BrowseNames.AckedState;
            instance.AckedState.Value      = new LocalizedText((acknowledged) ? ConditionStateNames.Acknowledged : ConditionStateNames.Unacknowledged);
            instance.AckedState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, acknowledged, false);

            instance.ActiveState            = new TwoStateVariableState(instance);
            instance.ActiveState.BrowseName = Opc.Ua.BrowseNames.ActiveState;
            instance.ActiveState.Value      = new LocalizedText((active) ? ConditionStateNames.Active : ConditionStateNames.Inactive);
            instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, active, false);
            instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.TransitionTime, ComUtils.GetDateTime(e.ftActiveTime), false);

            if (!String.IsNullOrEmpty(e.szSubconditionName))
            {
                instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EffectiveDisplayName, e.szSubconditionName, false);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Dispatches the event.
        /// </summary>
        private BaseEventState DispatchEvent(ONEVENTSTRUCT e)
        {
            NodeId typeId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, e.szConditionName, m_namespaceIndex);

            // find the type.
            AeEventTypeState eventType = m_cache.FindType(m_defaultContext, typeId);

            if (eventType == null)
            {
                return(null);
            }

            // create a new instance.
            BaseEventState instance = m_cache.CreateInstance(m_defaultContext, eventType);

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

            // fill in fields.
            UpdateBaseEvent(instance, eventType.EventType, e);

            if (instance is AuditEventState)
            {
                UpdateAuditEvent((AuditEventState)instance, eventType.EventType, e);
            }

            if (instance is AlarmConditionState)
            {
                UpdateAlarm((AlarmConditionState)instance, eventType.EventType, e);
            }

            if (instance is ExclusiveLimitAlarmState)
            {
                UpdateExclusiveLimitAlarm((ExclusiveLimitAlarmState)instance, eventType.EventType, e);
            }

            else if (instance is NonExclusiveLimitAlarmState)
            {
                UpdateNonExclusiveLimitAlarm((NonExclusiveLimitAlarmState)instance, eventType.EventType, e);
            }

            // process attributes.
            bool ackCommentFound = false;

            object[] values = ComUtils.GetVARIANTs(ref e.pEventAttributes, e.dwNumEventAttrs, false);

            for (int ii = 0; ii < eventType.EventType.Attributes.Count; ii++)
            {
                EventAttribute attribute = eventType.EventType.Attributes[ii];

                if (ii >= e.dwNumEventAttrs)
                {
                    continue;
                }

                if (!ackCommentFound && AeTypeCache.IsKnownName(attribute.Description, "ACK COMMENT"))
                {
                    ConditionState condition = instance as ConditionState;

                    if (condition != null)
                    {
                        condition.Comment            = new ConditionVariableState <LocalizedText>(condition);
                        condition.Comment.BrowseName = Opc.Ua.BrowseNames.Comment;
                        condition.Comment.Value      = new LocalizedText(values[ii] as string);
                    }

                    ackCommentFound = true;
                    continue;
                }

                PropertyState property = new PropertyState(instance);

                property.SymbolicName = attribute.Description;
                property.BrowseName   = new QualifiedName(property.SymbolicName, m_namespaceIndex);
                property.Value        = values[ii];

                instance.AddChild(property);
            }

            return(instance);
        }
        /// <summary>
        /// Called on a threadpool thread, SendEvents pops waiting event notifications from the
        /// subscription queue (subject to MaxSize) and invokes the client callback
        /// </summary>
        /// <param name="q"></param>
        /// <param name="bRefresh"></param>
        /// <param name="bKeepAlive"></param>
        public void SendEvents(EventItemQueue <OnEventClass> q, bool bRefresh, bool bKeepAlive)
        {
            int  dwCount             = 0;
            int  hClientSubscription = 0;
            bool bLastRefresh        = false;

            ONEVENTSTRUCT[] events;

            lock (m_csData)
            {
                hClientSubscription = m_hClientSubscription;
                dwCount             = Math.Min(q.Count, m_dwMaxSize);
                bLastRefresh        = (dwCount == q.Count) && bRefresh;
                events = new ONEVENTSTRUCT[dwCount];

                for (int i = 0; i < dwCount; i++)
                {
                    CopyToOnEventStruct(ref events[i], q.Dequeue());
                }
            }

            bool bUpdated = false;

            try
            {
                lock (m_lock)
                {
                    object callback = GetCallback(typeof(IOPCEventSink).GUID);

                    if (callback == null)
                    {
                        return;
                    }

                    if (dwCount > 0) // don't update time for a keep alive callback
                    {
                        m_LastUpdateTime = DateTime.Now;
                        bUpdated         = true;
                    }

                    if (bRefresh && bLastRefresh)
                    {
                        m_RefreshID = 0;
                    }

                    ((IOPCEventSink)callback).OnEvent(
                        hClientSubscription,
                        bRefresh ? 1 : 0,
                        bLastRefresh ? 1 : 0,
                        bKeepAlive ? 0 : dwCount,
                        events);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error in OnEvent callback.");
            }
            finally
            {
                for (int i = 0; i < dwCount; i++)
                {
                    Marshal.FreeCoTaskMem(events[i].pEventAttributes);
                }
            }

            if (m_server != null && bUpdated)
            {
                m_server.LastUpdateTime = m_LastUpdateTime;
            }
        }
Beispiel #13
0
        /// <summary>
        /// Marshals an event for return to the client.
        /// </summary>
        private OpcRcw.Ae.ONEVENTSTRUCT Translate(AeEvent e)
        {
            OpcRcw.Ae.ONEVENTSTRUCT e2 = new ONEVENTSTRUCT();

            e2.wNewState       = 0;
            e2.wChangeMask     = 0xFF;
            e2.szSource        = e.SourceName;
            e2.wQuality        = ComUtils.GetQualityCode(e.Quality);
            e2.dwEventType     = e.Category.EventType;
            e2.dwEventCategory = (int)e.Category.LocalId;
            e2.bAckRequired    = 0;
            e2.dwSeverity      = e.Severity;
            e2.ftTime          = ComUtils.GetFILETIME(e.Time);
            e2.szMessage       = (e.Message != null) ? e.Message.Text : null;
            e2.szActorID       = e.AuditUserId;
            e2.dwCookie        = e.Cookie;

            if (e.AttributeValues != null && e.AttributeValues.Length > 0)
            {
                e2.dwNumEventAttrs  = e.AttributeValues.Length;
                e2.pEventAttributes = ComUtils.GetVARIANTs(e.AttributeValues, true);
            }

            if ((e2.dwEventType & OpcRcw.Ae.Constants.CONDITION_EVENT) != 0)
            {
                e2.szConditionName = e.ConditionName;
                e2.ftActiveTime    = ComUtils.GetFILETIME(e.ActiveTime);
                e2.bAckRequired    = (e.AckedState)?0:1;

                // set the condition state.
                e2.wNewState = 0;

                if (e.EnabledState)
                {
                    e2.wNewState |= OpcRcw.Ae.Constants.CONDITION_ENABLED;
                }

                if (e.AckedState)
                {
                    e2.wNewState |= OpcRcw.Ae.Constants.CONDITION_ACKED;
                }

                if (e.ActiveState)
                {
                    e2.wNewState |= OpcRcw.Ae.Constants.CONDITION_ACTIVE;
                }

                // set the subcondition if available.
                if (!LocalizedText.IsNullOrEmpty(e.LowState))
                {
                    e2.szSubconditionName = e.LowState.Text;
                }

                if (!LocalizedText.IsNullOrEmpty(e.HighState))
                {
                    e2.szSubconditionName = e.HighState.Text;
                }

                if (!LocalizedText.IsNullOrEmpty(e.LowLowState))
                {
                    e2.szSubconditionName = e.LowLowState.Text;
                }

                if (!LocalizedText.IsNullOrEmpty(e.HighHighState))
                {
                    e2.szSubconditionName = e.HighHighState.Text;
                }

                if (!LocalizedText.IsNullOrEmpty(e.LimitState))
                {
                    e2.szSubconditionName = e.LimitState.Text;
                }
            }

            if (e2.szMessage == null)
            {
                e2.szMessage = String.Empty;
            }
            if (e2.szSource == null)
            {
                e2.szSource = String.Empty;
            }
            if (e2.szConditionName == null)
            {
                e2.szConditionName = String.Empty;
            }
            if (e2.szSubconditionName == null)
            {
                e2.szSubconditionName = String.Empty;
            }
            if (e2.szActorID == null)
            {
                e2.szActorID = String.Empty;
            }

            return(e2);
        }