Johan, Ack. Tested the sample applications.
Couple of comments. "ntf" entry to Makefile.common and configure.ac is to be done. The file saNtf.py is using SaAnyT, which is not imported. I shall make those changes and push today. Thanks, Srikanth On 11/06/2015 08:28 PM, Johan Mårtensson wrote: > opensaf.spec.in | 3 + > python/pyosaf/saNtf.py | 27 + > python/pyosaf/utils/Makefile.am | 3 +- > python/pyosaf/utils/ntf/Makefile.am | 22 + > python/pyosaf/utils/ntf/__init__.py | 657 > ++++++++++++++++++++++++++++++++++++ > python/samples/README | 11 + > python/samples/ntfsend | 251 +++++++++++++ > python/samples/ntfsubscribe | 307 ++++++++++++++++ > 8 files changed, 1280 insertions(+), 1 deletions(-) > > > Add high-level bindings and sample applications for NTF. A known issue > is that the assignment of additionalText is not working. > > Verify by using the ntfsend and ntfsubscribe sample applications. > > diff --git a/opensaf.spec.in b/opensaf.spec.in > --- a/opensaf.spec.in > +++ b/opensaf.spec.in > @@ -1524,6 +1524,9 @@ fi > %{python_sitelib}/pyosaf/utils/log/*.py > %{python_sitelib}/pyosaf/utils/log/*.pyc > %{python_sitelib}/pyosaf/utils/log/*.pyo > +%{python_sitelib}/pyosaf/utils/ntf/*.py > +%{python_sitelib}/pyosaf/utils/ntf/*.pyc > +%{python_sitelib}/pyosaf/utils/ntf/*.pyo > %{python_sitelib}/pyosaf/utils/immoi/*.py > %{python_sitelib}/pyosaf/utils/immoi/*.pyc > %{python_sitelib}/pyosaf/utils/immoi/*.pyo > diff --git a/python/pyosaf/saNtf.py b/python/pyosaf/saNtf.py > --- a/python/pyosaf/saNtf.py > +++ b/python/pyosaf/saNtf.py > @@ -176,6 +176,33 @@ eSaNtfValueTypeT = Enumeration(( > 'SA_NTF_VALUE_ARRAY', > )) > > +SaNtfValueTypeMap = { > + eSaNtfValueTypeT.SA_NTF_VALUE_UINT8: SaUint8T, > + eSaNtfValueTypeT.SA_NTF_VALUE_INT8: SaInt8T, > + eSaNtfValueTypeT.SA_NTF_VALUE_UINT16: SaUint16T, > + eSaNtfValueTypeT.SA_NTF_VALUE_INT16: SaInt16T, > + eSaNtfValueTypeT.SA_NTF_VALUE_UINT32: SaUint32T, > + eSaNtfValueTypeT.SA_NTF_VALUE_INT32: SaInt32T, > + eSaNtfValueTypeT.SA_NTF_VALUE_FLOAT: SaFloatT, > + eSaNtfValueTypeT.SA_NTF_VALUE_UINT64: SaUint64T, > + eSaNtfValueTypeT.SA_NTF_VALUE_INT64: SaInt64T, > + eSaNtfValueTypeT.SA_NTF_VALUE_DOUBLE: SaDoubleT, > + eSaNtfValueTypeT.SA_NTF_VALUE_LDAP_NAME: SaStringT, > + eSaNtfValueTypeT.SA_NTF_VALUE_STRING: SaStringT, > + eSaNtfValueTypeT.SA_NTF_VALUE_IPADDRESS: SaStringT, > + eSaNtfValueTypeT.SA_NTF_VALUE_BINARY: SaAnyT, > + eSaNtfValueTypeT.SA_NTF_VALUE_ARRAY: SaAnyT > +} > + > +def unmarshalSaNtfValue(void_ptr, value_type): > + """Convert void pointer to an instance of value type. > + """ > + val_ptr = SaNtfValueTypeMap.get(value_type) > + if val_ptr and void_ptr: > + if val_ptr == SaNameT: > + return cast(void_ptr, POINTER(val_ptr))[0].value > + return cast(void_ptr, POINTER(val_ptr))[0] > + return None > class _ptrVal(Structure): > _fields_ = [('dataOffset', SaUint16T), > ('dataSize', SaUint16T)] > diff --git a/python/pyosaf/utils/Makefile.am b/python/pyosaf/utils/Makefile.am > --- a/python/pyosaf/utils/Makefile.am > +++ b/python/pyosaf/utils/Makefile.am > @@ -25,4 +25,5 @@ SUBDIRS = \ > immom \ > clm \ > log \ > - immoi > + immoi \ > + ntf > diff --git a/python/pyosaf/utils/ntf/Makefile.am > b/python/pyosaf/utils/ntf/Makefile.am > new file mode 100644 > --- /dev/null > +++ b/python/pyosaf/utils/ntf/Makefile.am > @@ -0,0 +1,22 @@ > +# -*- OpenSAF -*- > +# > +# (C) Copyright 2011 The OpenSAF Foundation > +# > +# This program is distributed in the hope that it will be useful, but > +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY > +# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed > +# under the GNU Lesser General Public License Version 2.1, February 1999. > +# The complete license can be accessed from the following location: > +# http://opensource.org/licenses/lgpl-license.php > +# See the Copying file included with the OpenSAF distribution for full > +# licensing terms. > +# > +# Author(s): Oracle > +# > + > +include $(top_srcdir)/Makefile.common > + > +MAINTAINERCLEANFILES = Makefile.in > + > +pkgpyosafutilsntf_PYTHON = \ > + __init__.py > diff --git a/python/pyosaf/utils/ntf/__init__.py > b/python/pyosaf/utils/ntf/__init__.py > new file mode 100644 > --- /dev/null > +++ b/python/pyosaf/utils/ntf/__init__.py > @@ -0,0 +1,657 @@ > +############################################################################ > +# > +# (C) Copyright 2015 The OpenSAF Foundation > +# > +# This program is distributed in the hope that it will be useful, but > +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY > +# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed > +# under the GNU Lesser General Public License Version 2.1, February 1999. > +# The complete license can be accessed from the following location: > +# http://opensource.org/licenses/lgpl-license.php > +# See the Copying file included with the OpenSAF distribution for full > +# licensing terms. > +# > +# Author(s): Ericsson > +# > +############################################################################ > + > +''' > + NTF common utilities > +''' > + > +from pyosaf import saNtf, saAis > +import ctypes > + > +from pyosaf.utils import decorate > + > +saNtfInitialize = decorate(saNtf.saNtfInitialize) > +saNtfLocalizedMessageFree = decorate(saNtf.saNtfLocalizedMessageFree) > +saNtfStateChangeNotificationFilterAllocate = > decorate(saNtf.saNtfStateChangeNotificationFilterAllocate) > +saNtfNotificationUnsubscribe = > decorate(saNtf.saNtfNotificationUnsubscribe) > +saNtfNotificationReadInitialize = > decorate(saNtf.saNtfNotificationReadInitialize) > +saNtfInitialize_2 = decorate(saNtf.saNtfInitialize_2) > +saNtfNotificationReadInitialize_2 = > decorate(saNtf.saNtfNotificationReadInitialize_2) > +saNtfNotificationSubscribe = decorate(saNtf.saNtfNotificationSubscribe) > +saNtfInitialize_3 = decorate(saNtf.saNtfInitialize_3) > +saNtfSelectionObjectGet = decorate(saNtf.saNtfSelectionObjectGet) > +saNtfDispatch = decorate(saNtf.saNtfDispatch) > +saNtfFinalize = decorate(saNtf.saNtfFinalize) > +saNtfObjectCreateDeleteNotificationAllocate = > decorate(saNtf.saNtfObjectCreateDeleteNotificationAllocate) > +saNtfAttributeChangeNotificationAllocate = > decorate(saNtf.saNtfAttributeChangeNotificationAllocate) > +saNtfStateChangeNotificationAllocate = > decorate(saNtf.saNtfStateChangeNotificationAllocate) > +saNtfStateChangeNotificationAllocate_3 = > decorate(saNtf.saNtfStateChangeNotificationAllocate_3) > +saNtfAlarmNotificationAllocate = > decorate(saNtf.saNtfAlarmNotificationAllocate) > +saNtfSecurityAlarmNotificationAllocate = > decorate(saNtf.saNtfSecurityAlarmNotificationAllocate) > +saNtfMiscellaneousNotificationAllocate = > decorate(saNtf.saNtfMiscellaneousNotificationAllocate) > +saNtfPtrValAllocate = decorate(saNtf.saNtfPtrValAllocate) > +saNtfArrayValAllocate = decorate(saNtf.saNtfArrayValAllocate) > +saNtfIdentifierAllocate = decorate(saNtf.saNtfIdentifierAllocate) > +saNtfNotificationSend = decorate(saNtf.saNtfNotificationSend) > +saNtfNotificationSendWithId = decorate(saNtf.saNtfNotificationSendWithId) > +saNtfNotificationFree = decorate(saNtf.saNtfNotificationFree) > +saNtfVariableDataSizeGet = decorate(saNtf.saNtfVariableDataSizeGet) > +saNtfLocalizedMessageGet = decorate(saNtf.saNtfLocalizedMessageGet) > +saNtfLocalizedMessageFree_2 = decorate(saNtf.saNtfLocalizedMessageFree_2) > +saNtfPtrValGet = decorate(saNtf.saNtfPtrValGet) > +saNtfArrayValGet = decorate(saNtf.saNtfArrayValGet) > +saNtfObjectCreateDeleteNotificationFilterAllocate = > decorate(saNtf.saNtfObjectCreateDeleteNotificationFilterAllocate) > +saNtfAttributeChangeNotificationFilterAllocate = > decorate(saNtf.saNtfAttributeChangeNotificationFilterAllocate) > +saNtfStateChangeNotificationFilterAllocate_2 = > decorate(saNtf.saNtfStateChangeNotificationFilterAllocate_2) > +saNtfAlarmNotificationFilterAllocate = > decorate(saNtf.saNtfAlarmNotificationFilterAllocate) > +saNtfSecurityAlarmNotificationFilterAllocate = > decorate(saNtf.saNtfSecurityAlarmNotificationFilterAllocate) > +saNtfNotificationFilterFree = decorate(saNtf.saNtfNotificationFilterFree) > +saNtfNotificationSubscribe_3 = > decorate(saNtf.saNtfNotificationSubscribe_3) > +saNtfNotificationReadInitialize_3 = > decorate(saNtf.saNtfNotificationReadInitialize_3) > +saNtfNotificationUnsubscribe_2 = > decorate(saNtf.saNtfNotificationUnsubscribe_2) > +saNtfNotificationReadNext = decorate(saNtf.saNtfNotificationReadNext) > +saNtfNotificationReadNext_3 = decorate(saNtf.saNtfNotificationReadNext_3) > +saNtfNotificationReadFinalize = > decorate(saNtf.saNtfNotificationReadFinalize) > + > + > +HANDLE = saNtf.SaNtfHandleT() > +SELECTION_OBJECT = saAis.SaSelectionObjectT() > +CALLBACKS = saNtf.SaNtfCallbacksT() > + > + > +class AdditionalInfo(object): > + ''' Represents a piece of additional info to be included in a > + notification > + ''' > + > + def __init__(self, info_id, info_type, info_value): > + self.info_id = info_id > + self.info_type = info_type > + self.info_value = info_value > + > + > +class StateChange(object): > + ''' Contains information about a state change event''' > + > + def __init__(self): > + pass > + > + > +class AttributeChange(object): > + ''' Contains information about a change in an attribute''' > + > + def __init__(self): > + pass > + > + > +class Attribute(object): > + ''' Contains information about the value and value type of an > attribute''' > + > + def __init__(self): > + pass > + > + > +class SecurityAlarmDetector(object): > + ''' Represents an instance of a security alarm detector''' > + > + def __init__(self, value=None, value_type=None): > + self.value = value > + self.value_type = value_type > + > + > +class ServiceUser(object): > + ''' Represents a service user''' > + > + def __init__(self, value=None, value_type=None): > + self.value = value > + self.value_type = value_type > + > + > +class ServiceProvider(object): > + ''' Represents a service provider''' > + > + def __init__(self, value=None, value_type=None): > + self.value = value > + self.value_type = value_type > + > + > +def dummy_func(*args): > + ''' Dummy function used as a callback when no proper callbacks are set''' > + pass > + > +def initialize(notification_callback=None): > + ''' Initializes the NTF library''' > + > + # Initialize the NTF API > + version = saAis.SaVersionT('A', 1, 1) > + > + # Assign default values for callbacks > + CALLBACKS.saNtfNotificationCallback = \ > + saNtf.SaNtfNotificationCallbackT(dummy_func) > + CALLBACKS.saNtfNotificationDiscardedCallback = \ > + saNtf.SaNtfNotificationDiscardedCallbackT(dummy_func) > + > + # Override the notification subscribe callback if it's passed > + if notification_callback: > + CALLBACKS.saNtfNotificationCallback = \ > + saNtf.SaNtfNotificationCallbackT(notification_callback) > + > + # Initialize the API > + saNtfInitialize(HANDLE, CALLBACKS, version) > + > + # Get the selection object > + saNtfSelectionObjectGet(HANDLE, SELECTION_OBJECT) > + > + > +def assign_ntf_value_to_attribute(attr_value_field, value, value_type): > + ''' Assigns the correct sub-field in the given attribute > + > + e.g. attr_value_field.uint8Val = ... > + > + ''' > + > + if value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT8: > + attr_value_field.uint8Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT8: > + attr_value_field.int8Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT16: > + attr_value_field.uint16Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT16: > + attr_value_field.int16Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT32: > + attr_value_field.uint32Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT32: > + attr_value_field.int32Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_FLOAT: > + attr_value_field.floatVal = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT64: > + attr_value_field.uint64Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT64: > + attr_value_field.int64Val = value > + > + elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_DOUBLE: > + attr_value_field.doubleVal = value > + > + > +def fill_in_header(notification_handle, > + header, notification_object, notifying_object, vendor_id, > + major_id, minor_id, additional_text, event_type, > event_time, > + additional_info): > + ''' Fills in the given notification header with the provided values''' > + > + header.eventType.contents.value = event_type > + header.notificationObject.contents.value = notification_object > + header.notificationObject.contents.length = len(notification_object) > + header.notifyingObject.contents.value = notifying_object > + header.notifyingObject.contents.length = len(notifying_object) > + header.notificationClassId.contents.vendorId = vendor_id > + header.notificationClassId.contents.majorId = major_id > + header.notificationClassId.contents.minorId = minor_id > + header.eventTime.contents.value = event_time > + header.numCorrelatedNotifications = 0 > + header.lengthAdditionalText = len(additional_text) > + > + ## > + ## FIXME: this fails to copy the value of the additional_text variable > into > + ## header.additionalText. > + > + ctypes.memmove(header.additionalText, > + additional_text, > + len(additional_text)) > + > + header.numAdditionalInfo = len(additional_info) > + header.thresholdInformation = None > + > + # Fill in additional info > + if additional_info != []: > + for i in range(0, len(additional_info)): > + > + header.additionalInfo[i].infoId = additional_info[i].info_id > + header.additionalInfo[i].infoType = additional_info[i].info_type > + > + dest_ptr = (ctypes.c_char * len(additional_info[i].info_value))() > + > + saNtf.saNtfPtrValAllocate(notification_handle, > + len(additional_info[i].info_value) + 1, > + dest_ptr, > + header.additionalInfo[i].infoValue) > + > + ctypes.memmove(ctypes.addressof(dest_ptr), > + additional_info[i].info_value, > + len(additional_info[i].info_value) + 1) > + > + else: > + header.additionalInfo = None > + > + > +def send_object_create_notification(vendor_id, major_id, minor_id, > + additional_text="", > + notification_object="", > + notifying_object="", > + attributes=[], > + event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[]): > + ''' Sends a notification for a created object''' > + > + _send_object_create_delete_notification( > + saNtf.eSaNtfEventTypeT.SA_NTF_OBJECT_CREATION, > + vendor_id, major_id, minor_id, > + additional_text=additional_text, > + notification_object=notification_object, > + notifying_object=notifying_object, > + attributes=attributes, > + event_time=event_time, > + additional_info=additional_info) > + > + > +def send_object_delete_notification(vendor_id, > + major_id, > + minor_id, > + additional_text="", > + notification_object="", > + notifying_object="", > + attributes=[], > + event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[]): > + ''' Sends a notification for a deleted object''' > + > + _send_object_create_delete_notification( > + saNtf.eSaNtfEventTypeT.SA_NTF_OBJECT_DELETION, > + vendor_id, major_id, minor_id, > + additional_text=additional_text, > + notification_object=notification_object, > + notifying_object=notifying_object, > + attributes=attributes, > + event_time=event_time, > + additional_info=additional_info) > + > + > +def _send_object_create_delete_notification( > + event_type, > + vendor_id, > + major_id, > + minor_id, > + additional_text="", > + notification_object="", > + notifying_object="", > + attributes=[], > + event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[]): > + ''' Sends an object create delete notification''' > + > + # Create the notification > + notification = saNtf.SaNtfObjectCreateDeleteNotificationT() > + > + saNtfObjectCreateDeleteNotificationAllocate( > + HANDLE, > + notification, > + 0, > + len(additional_text) + 1, > + len(additional_info), > + len(attributes), > + 0) > + > + # Fill in the header > + fill_in_header(notification.notificationHandle, > + notification.notificationHeader, > + notification_object, notifying_object, vendor_id, > + major_id, minor_id, additional_text, > + event_type, event_time, additional_info) > + > + # Fill in attributes > + for i in range(0, notification.numAttributes): > + > + ptr = notification.objectAttributes[i] > + > + ptr.attributeId = attributes[i].attribute_id > + ptr.attributeType = attributes[i].attribute_type > + > + assign_ntf_value_to_attribute(ptr.attributeValue, > + attributes[i].attribute_value, > + attributes[i].attribute_type) > + > + > + # Send the notification > + saNtfNotificationSend(notification.notificationHandle) > + > + # Free the notification > + saNtfNotificationFree(notification.notificationHandle) > + > + > +def send_state_change_notification(vendor_id, > + major_id, > + minor_id, > + additional_text="", > + notification_object="", > + notifying_object="", > + event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[], > + state_changes=[]): > + ''' Sends a state change notification''' > + > + event_type = saNtf.eSaNtfEventTypeT.SA_NTF_OBJECT_STATE_CHANGE > + > + # Create the notification > + notification = saNtf.SaNtfStateChangeNotificationT() > + > + saNtfStateChangeNotificationAllocate( > + HANDLE, > + notification, > + 0, > + len(additional_text) + 1, > + len(additional_info), > + len(state_changes), > + 0) > + > + # Fill in the header > + fill_in_header(notification.notificationHandle, > + notification.notificationHeader, > + notification_object, notifying_object, vendor_id, > + major_id, minor_id, additional_text, event_type, > + event_time, additional_info) > + > + # Fill in state changes > + > + for i in range(0, len(state_changes)): > + > + notification.changedStates[i].stateId = state_changes[i].state_id > + > + if state_changes[i].old_state_present: > + notification.changedStates[i].oldStatePresent = > saAis.eSaBoolT.SA_TRUE > + notification.changedStates[i].oldState = > state_changes[i].old_state > + > + else: > + notification.changedStates[i].oldStatePresent = > saAis.eSaBoolT.SA_FALSE > + > + notification.changedStates[i].newState = state_changes[i].new_state > + > + # Send the alarm notification > + saNtfNotificationSend(notification.notificationHandle) > + > + # Free the alarm notification > + saNtfNotificationFree(notification.notificationHandle) > + > + > +def send_attribute_change_notification(vendor_id, > + major_id, > + minor_id, > + additional_text="", > + notification_object="", > + notifying_object="", > + > event_type=saNtf.eSaNtfEventTypeT.SA_NTF_ATTRIBUTE_ADDED, > + > event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[], > + changed_attributes=[]): > + ''' Sends an attribute_change notification''' > + > + # Create the notification > + notification = saNtf.SaNtfAttributeChangeNotificationT() > + > + saNtfAttributeChangeNotificationAllocate( > + HANDLE, > + notification, > + 0, > + len(additional_text) + 1, > + len(additional_info), > + len(changed_attributes), > + 0) > + > + # Fill in the header > + fill_in_header(notification.notificationHandle, > + notification.notificationHeader, > + notification_object, notifying_object, vendor_id, > + major_id, minor_id, additional_text, event_type, > + event_time, additional_info) > + > + > + # Fill in attributes > + for i in range(0, len(changed_attributes)): > + > + ptr = notification.changedAttributes[i] > + > + ptr.attributeId = changed_attributes[i].attribute_id > + ptr.attributeType = changed_attributes[i].attribute_type > + > + if changed_attributes[i].old_attribute_present: > + ptr.oldAttributePresent = saAis.eSaBoolT.SA_TRUE > + > + assign_ntf_value_to_attribute(ptr.oldAttributeValue, > + > changed_attributes[i].old_attribute_value, > + > changed_attributes[i].attribute_type) > + > + else: > + ptr.oldAttributePresent = saAis.eSaBoolT.SA_FALSE > + > + assign_ntf_value_to_attribute(ptr.newAttributeValue, > + > changed_attributes[i].new_attribute_value, > + changed_attributes[i].attribute_type) > + > + # Send the alarm notification > + saNtfNotificationSend(notification.notificationHandle) > + > + # Free the alarm notification > + saNtfNotificationFree(notification.notificationHandle) > + > + > +def send_security_alarm_notification(vendor_id, major_id, minor_id, severity, > + alarm_detector, > + user, > + provider, > + additional_text="", > + notification_object="", > + notifying_object="", > + > event_type=saNtf.eSaNtfEventTypeT.SA_NTF_INTEGRITY_VIOLATION, > + event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[], > + > probable_cause=saNtf.eSaNtfProbableCauseT.SA_NTF_SOFTWARE_ERROR): > + > + ''' Sends a security alarm notification''' > + > + # Create the notification > + notification = saNtf.SaNtfSecurityAlarmNotificationT() > + > + saNtfSecurityAlarmNotificationAllocate( > + HANDLE, > + notification, > + 0, > + len(additional_text) + 1, > + len(additional_info), > + 0) > + > + # Fill in the header > + fill_in_header(notification.notificationHandle, > + notification.notificationHeader, > + notification_object, notifying_object, vendor_id, > + major_id, minor_id, additional_text, event_type, > + event_time, additional_info) > + > + # Fill in security alarm-specific fields > + notification.probableCause.contents.value = probable_cause > + notification.severity.contents.value = severity > + > + assign_ntf_value_to_attribute(notification.securityAlarmDetector, > + alarm_detector.value, > + alarm_detector.value_type) > + > + assign_ntf_value_to_attribute(notification.serviceUser, > + user.value, > + user.value_type) > + > + assign_ntf_value_to_attribute(notification.serviceProvider, > + provider.value, > + provider.value_type) > + > + # Send the alarm notification > + saNtfNotificationSend(notification.notificationHandle) > + > + # Free the alarm notification > + saNtfNotificationFree(notification.notificationHandle) > + > + > +def send_alarm_notification(vendor_id, major_id, minor_id, severity, > + additional_text="", > + notification_object="", > + notifying_object="", > + > event_type=saNtf.eSaNtfEventTypeT.SA_NTF_ALARM_PROCESSING, > + event_time=saAis.saAis.SA_TIME_UNKNOWN, > + additional_info=[]): > + ''' Sends an alarm notification''' > + > + # Create the notification > + notification = saNtf.SaNtfAlarmNotificationT() > + > + saNtfAlarmNotificationAllocate( > + HANDLE, > + notification, > + 0, > + len(additional_text) + 1, > + len(additional_info), > + 0, > + 0, > + 0, > + 0) > + > + # Fill in the header > + fill_in_header(notification.notificationHandle, > + notification.notificationHeader, > + notification_object, notifying_object, vendor_id, > + major_id, minor_id, additional_text, event_type, > + event_time, additional_info) > + > + notification.numMonitoredAttributes = 0 > + notification.numSpecificProblems = 0 > + notification.numProposedRepairActions = 0 > + notification.perceivedSeverity.contents.value = severity > + notification.probableCause.contents.value = \ > + > saNtf.eSaNtfProbableCauseT.SA_NTF_DEGRADED_SIGNAL > + > + # Send the alarm notification > + saNtfNotificationSend(notification.notificationHandle) > + > + # Free the alarm notification > + saNtfNotificationFree(notification.notificationHandle) > + > + > +def subscribe_for_notifications(notification_types=None): > + ''' Subscribes for notifications from NTF. The types of notifications to > + subscribe to are passed in the notification_types list and > + subscriptions are set up for all types if the list is empty > + ''' > + > + filters = [] > + > + filter_handles = saNtf.SaNtfNotificationTypeFilterHandlesT() > + > + filter_handles.objectCreateDeleteFilterHandle = > saNtf.SaNtfNotificationFilterHandleT(0) > + filter_handles.attributeChangeFilterHandle = > saNtf.SaNtfNotificationFilterHandleT(0) > + filter_handles.stateChangeFilterHandle = > saNtf.SaNtfNotificationFilterHandleT(0) > + filter_handles.alarmFilterHandle = > saNtf.SaNtfNotificationFilterHandleT(0) > + filter_handles.securityFilterHandle = > saNtf.SaNtfNotificationFilterHandleT(0) > + > + > + # Create and allocate the alarm filter > + if not notification_types or \ > + saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ALARM in notification_types: > + notification_filter = saNtf.SaNtfAlarmNotificationFilterT() > + > + saNtfAlarmNotificationFilterAllocate(HANDLE, notification_filter, > + 0, 0, 0, 0, 0, 0, 0) > + > + filter_handles.alarmFilterHandle = > notification_filter.notificationFilterHandle > + > + filters.append(notification_filter.notificationFilterHandle) > + > + # Create and allocate the object create delete filter > + if not notification_types or \ > + saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_OBJECT_CREATE_DELETE in > notification_types: > + notification_filter = > saNtf.SaNtfObjectCreateDeleteNotificationFilterT() > + > + saNtfObjectCreateDeleteNotificationFilterAllocate(HANDLE, > + > notification_filter, > + 0, 0, 0, 0, 0) > + > + filter_handles.objectCreateDeleteFilterHandle = > notification_filter.notificationFilterHandle > + filters.append(notification_filter.notificationFilterHandle) > + > + # Create and allocate the attribute change filter > + if not notification_types or \ > + saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ATTRIBUTE_CHANGE in > notification_types: > + > + notification_filter = saNtf.SaNtfAttributeChangeNotificationFilterT() > + > + saNtfAttributeChangeNotificationFilterAllocate(HANDLE, > + notification_filter, > + 0, 0, 0, 0, 0) > + > + filter_handles.attributeChangeFilterHandle = > notification_filter.notificationFilterHandle > + > + filters.append(notification_filter.notificationFilterHandle) > + > + # Create and allocate the state change filter > + if not notification_types or \ > + saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_STATE_CHANGE in > notification_types: > + > + notification_filter = saNtf.SaNtfStateChangeNotificationFilterT() > + > + saNtfStateChangeNotificationFilterAllocate(HANDLE, > + notification_filter, > + 0, 0, 0, 0, 0, 0) > + > + filter_handles.stateChangeFilterHandle = > notification_filter.notificationFilterHandle > + > + filters.append(notification_filter.notificationFilterHandle) > + > + # Create and allocate the security alarm filter > + if not notification_types or \ > + saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_SECURITY_ALARM in > notification_types: > + > + notification_filter = saNtf.SaNtfSecurityAlarmNotificationFilterT() > + > + saNtfSecurityAlarmNotificationFilterAllocate(HANDLE, > + notification_filter, > + 0, 0, 0, 0, 0, 0, 0, 0, > 0) > + > + filter_handles.securityAlarmFilterHandle = > notification_filter.notificationFilterHandle > + > + filters.append(notification_filter.notificationFilterHandle) > + > + # Create a unique subscription id > + sub_id = saNtf.SaNtfSubscriptionIdT(1) > + > + # Start subscription > + saNtfNotificationSubscribe(filter_handles, sub_id) > + > + # Free up the filters > + for filter_handle in filters: > + saNtfNotificationFilterFree(filter_handle) > + > + > +def dispatch(mode=saAis.eSaDispatchFlagsT.SA_DISPATCH_ALL): > + ''' Invokes NTF callbacks for queued events. The default is to dispatch > all > + available events > + ''' > + > + saNtfDispatch(HANDLE, mode) > + > diff --git a/python/samples/README b/python/samples/README > --- a/python/samples/README > +++ b/python/samples/README > @@ -74,6 +74,17 @@ interface-handler: > netifaces library to do so. Run 'interface-handler --help' for > specific options and arguments. > > +ntfsend: > + The ntfsend sample application is a copy of the ntfsend tool, > + implemented in Python. It sends notifications through NTF. Run > + 'ntfsend --help' for specific options and arguments. > + > +ntfsubscribe: > + The ntfsubscribe sample application is a copy of the > + ntfsubscribe tool, implemented in Python. It listens for > + notifications and logs received notifications in the > + terminal. Run 'ntfsubscribe --help'. > + > Logging for all apps/utils goes to /var/log/opensaf/saflog/saLogSystem*.log > > The IMM OI samples use the classes defined in the classes.xml file. Load it > with immcfg -f classes.xml before trying them. > diff --git a/python/samples/ntfsend b/python/samples/ntfsend > new file mode 100755 > --- /dev/null > +++ b/python/samples/ntfsend > @@ -0,0 +1,251 @@ > +#! /usr/bin/env python > + > +import argparse > +import time > + > +from pyosaf import saNtf, saAis > +from pyosaf.utils import ntf > + > + > +def construct_additional_info(additional_info_string): > + ''' Constructs an AdditionalInfo instance from the given string. > + > + The string must be of the format ID,TYPE,VALUE > + ''' > + > + info_id = int(additional_info_string.split(',')[0]) > + info_type = int(additional_info_string.split(',')[1]) > + info_value = ','.join(additional_info_string.split(',')[2:]) > + > + return ntf.AdditionalInfo(info_id, info_type, info_value) > + > + > +if __name__ == '__main__': > + > + # Parse command line arguments > + parser = argparse.ArgumentParser( > + description='ntfsend is a SAF NTF client used to send a > notificaiton.') > + > + parser.add_argument('--notificationType', '-T', > metavar='0x1000...0x5000', > + default='0x4000', > + help='numeric value of SaNtfNotificationTypeT' > + > '(obj_create_del=0x1000,attr_ch,state_ch,al,sec_al=0x5000)') > + parser.add_argument('--eventType', '-e', metavar='4096...24589', > + help='numeric value of SaNtfEventTypeT' > + > '(SA_NTF_OBJECT_NOTIFICATIONS_START...SA_NTF_HPI_EVENT_OTHER)') > + parser.add_argument('--eventTime', '-E', metavar='TIME', > + default=saAis.saAis.SA_TIME_UNKNOWN, > + help='numeric value of SaTimeT') > + parser.add_argument('--notificationClassId', '-c', metavar='VE,MA,MI', > + default='162,1,1', > + help='vendorid, majorid, minorid') > + parser.add_argument('--notificationObject', '-n', metavar='NOT_OBJ', > + default="", > + help='notification object (string value)') > + parser.add_argument('--notifyingObject', '-N', metavar='NOTIFY_OBJ', > + default="", > + help='notififying object (string value)') > + parser.add_argument('--additionalText', '-a', metavar='TEXT', > + default="", > + help='additional text (string value)') > + parser.add_argument('--probableCause', '-p', metavar='0..74', > + help='numeric value SaNtfProbableCauseT' > + 'SA_NTF_ADAPTER_ERROR to SA_NTF_UNSPECIFIED_REASON') > + parser.add_argument('--perceivedSeverity', '-s', metavar='0...5', > + type=int, default='4', > + help='severity numeric value' > + '(clear=0,ind,warn,min,maj,crit=5)') > + parser.add_argument('--repeatSends', '-r', metavar='NUM', > + default=1, type=int, > + help='send the same notifification NUM times') > + parser.add_argument('--burstTimeout', '-b', metavar='TIME', > + default=0, type=int, > + help='send burst of NUM repeatSends ' > + '[default: 1] and sleep TIME (usec)' > + 'between each burst, will continue for ever') > + parser.add_argument('--additionalInfo', '-i', metavar='ID,TYPE,VALUE', > + help='additional information' > + 'ID: SaNtfElementIdT integer value' > + 'TYPE: numeric value SaNtfValueTypeT, only ' > + 'SA_NTF_VALUE_STRING=11 is supported') > + > + args = parser.parse_args() > + > + # Fill in arguments > + vendor_id = int(args.notificationClassId.split(',')[0]) > + major_id = int(args.notificationClassId.split(',')[1]) > + minor_id = int(args.notificationClassId.split(',')[2]) > + > + event_time = int(args.eventTime) > + > + severity = int(args.perceivedSeverity) > + > + additional_text = args.additionalText > + notification_object = args.notificationObject > + notifying_object = args.notifyingObject > + > + # Initialize the NTF library > + ntf.initialize() > + > + # Send the notification > + ntf_type = int(args.notificationType, 0) > + > + if ntf_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_OBJECT_CREATE_DELETE: > + > + # Create sample attributes > + attributes = [] > + > + attr1 = ntf.Attribute() > + > + attr1.attribute_id = 1 > + attr1.attribute_type = saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT16 > + attr1.attribute_value = 23 > + > + attributes.append(attr1) > + > + attr2 = ntf.Attribute() > + > + attr2.attribute_id = 2 > + attr2.attribute_type = saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT32 > + attr2.attribute_value = -3 > + > + attributes.append(attr2) > + > + # Create sample additional info > + additional_info = [] > + if args.additionalInfo: > + > additional_info.append(construct_additional_info(args.additionalInfo)) > + > + # Send the notification > + for i in range(0, args.repeatSends): > + ntf.send_object_create_notification(vendor_id, > + major_id, > + minor_id, > + > additional_text=additional_text, > + > notification_object=notification_object, > + > notifying_object=notifying_object, > + attributes=attributes, > + event_time=event_time, > + > additional_info=additional_info) > + > + time.sleep(args.burstTimeout) > + > + elif ntf_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_SECURITY_ALARM: > + > + # Create security alarm sample fields > + > + detector = ntf.SecurityAlarmDetector( > + value=15, > + value_type=saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT32 > + ) > + > + user = ntf.ServiceUser( > + value=-2, > + value_type=saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT16 > + ) > + > + provider = ntf.ServiceProvider( > + value=128, > + value_type=saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT32 > + ) > + > + # Send the notification > + for i in range(0, args.repeatSends): > + ntf.send_security_alarm_notification(vendor_id, major_id, > minor_id, severity, > + detector, user, provider, > + > additional_text=additional_text, > + > notification_object=notification_object, > + > notifying_object=notifying_object, > + event_time=event_time) > + > + time.sleep(args.burstTimeout) > + > + elif ntf_type == saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ALARM: > + > + for i in range(0, args.repeatSends): > + ntf.send_alarm_notification(vendor_id, major_id, minor_id, > severity, > + additional_text=additional_text, > + > notification_object=notification_object, > + notifying_object=notifying_object, > + event_time=event_time) > + > + time.sleep(args.burstTimeout) > + > + elif ntf_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ATTRIBUTE_CHANGE: > + > + # Fill in sample attribute changes > + > + attr0 = ntf.AttributeChange() > + > + attr0.attribute_id = 0 > + attr0.attribute_type = saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT32 > + attr0.old_attribute_present = saAis.eSaBoolT.SA_FALSE > + attr0.new_attribute_value = 1 > + > + attr1 = ntf.AttributeChange() > + > + attr1.attribute_id = 1 > + attr1.attribute_type = saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT32 > + attr1.old_attribute_present = saAis.eSaBoolT.SA_TRUE > + attr1.old_attribute_value = 8 > + attr1.new_attribute_value = -4 > + > + changed_attributes = [attr0, attr1] > + > + # Send the notification > + for i in range(0, args.repeatSends): > + ntf.send_attribute_change_notification(vendor_id, major_id, > minor_id, > + > additional_text=additional_text, > + > notification_object=notification_object, > + > notifying_object=notifying_object, > + event_time=event_time, > + > changed_attributes=changed_attributes) > + > + time.sleep(args.burstTimeout) > + > + elif ntf_type == saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_STATE_CHANGE: > + > + # Fill in sample state changes > + changes = [] > + > + change0 = ntf.StateChange() > + > + change0.state_id = 1 > + change0.old_state_present = False > + change0.new_state = 0 > + > + change1 = ntf.StateChange() > + > + change1.state_id = 2 > + change1.old_state_present = False > + change1.new_state = 5 > + > + change2 = ntf.StateChange() > + > + change2.state_id = 1 > + change2.old_state_present = True > + change2.old_state = 0 > + change2.new_state = 1 > + > + change3 = ntf.StateChange() > + > + change3.state_id = 2 > + change3.old_state_present = True > + change3.old_state = 5 > + change3.new_state = 10 > + > + changes.append(change0) > + changes.append(change1) > + changes.append(change2) > + changes.append(change3) > + > + # Send the notification > + for i in range(0, args.repeatSends): > + ntf.send_state_change_notification(vendor_id, major_id, minor_id, > + > additional_text=additional_text, > + > notification_object=notification_object, > + > notifying_object=notifying_object, > + event_time=event_time, > + state_changes=changes) > + > + time.sleep(args.burstTimeout) > diff --git a/python/samples/ntfsubscribe b/python/samples/ntfsubscribe > new file mode 100755 > --- /dev/null > +++ b/python/samples/ntfsubscribe > @@ -0,0 +1,307 @@ > +#! /usr/bin/env python > + > +import select > +import ctypes > +import datetime > +import argparse > + > +from pyosaf import saNtf, saAis > +from pyosaf.utils import ntf > + > +def SaNameT_to_string(name): > + ''' Converts an instance of SaNameT to a Python string''' > + > + return ctypes.create_string_buffer(name.value, name.length).value > + > +def p_char_to_string(p_char, length): > + ''' Converts a char pointer with a missing NULL pointer to a string with > the > + given length''' > + > + return ctypes.create_string_buffer(p_char, length).value > + > +def SaTimeT_to_date_string(sa_time): > + ''' Returns a string representation for the given SaTimeT instance''' > + > + milli_seconds = sa_time / 1000000 > + > + return datetime.datetime.fromtimestamp(milli_seconds/1000).isoformat() > + > +def print_notification_header(header): > + ''' Prints the given notification header''' > + > + class_id = header.notificationClassId.contents > + > + print '''eventType = %s > +notificationObject = "%s" > +notifyingObject = "%s" > +notificationClassId = %d.%d.%d (0x0) > +additionalText = "%s"''' % ( > + saNtf.eSaNtfEventTypeT.whatis(header.eventType.contents.value), > + SaNameT_to_string(header.notificationObject.contents), > + SaNameT_to_string(header.notifyingObject.contents), > + class_id.vendorId, > + class_id.majorId, > + class_id.minorId, > + p_char_to_string(header.additionalText, header.lengthAdditionalText) > +) > + > + > +def print_alarm_notification(notification): > + ''' Prints the given alarm notification''' > + > + header = notification.notificationHeader > + > + print '=== %s - Alarm ===' % > SaTimeT_to_date_string(header.eventTime.contents.value) > + > + print_notification_header(header) > + > + print 'probableCause = %s' % \ > + > saNtf.eSaNtfProbableCauseT.whatis(notification.probableCause.contents.value) > + print 'perceivedSeverity = %s' % \ > + > saNtf.eSaNtfSeverityT.whatis(notification.perceivedSeverity.contents.value) > + > + > +def print_object_create_delete_notification(notification): > + ''' Prints the given object create delete notification''' > + > + header = notification.notificationHeader > + > + print '=== %s - Object Create/Delete ===' % > SaTimeT_to_date_string(header.eventTime.contents.value) > + > + print_notification_header(header) > + > + print 'sourceIndicator = %s' % \ > + > saNtf.eSaNtfSourceIndicatorT.whatis(notification.sourceIndicator.contents.value) > + > + print > + > + print 'numAttributes: %d' % notification.numAttributes > + > + for i in range(0, notification.numAttributes): > + > + c_attribute = notification.objectAttributes[i] > + > + print '- Attribute ID: %d -' % c_attribute.attributeId > + print ' Attribute Type: (%d) %s' % ( > + c_attribute.attributeType, > + saNtf.eSaNtfValueTypeT.whatis(c_attribute.attributeType) > + ) > + > + print ' Attribute Value: %d' % \ > + saNtf.unmarshalSaNtfValue(saAis.BYREF(c_attribute.attributeValue), > + c_attribute.attributeType) > + > + > +def print_attribute_change_notification(notification): > + ''' Prints the given attribute change notification''' > + > + header = notification.notificationHeader > + > + print '=== %s - Attribute Change ===' % > SaTimeT_to_date_string(header.eventTime.contents.value) > + > + print_notification_header(header) > + > + print 'sourceIndicator = %s' % \ > + > saNtf.eSaNtfSourceIndicatorT.whatis(notification.sourceIndicator.contents.value) > + > + print > + > + print 'numAttributes: %d' % notification.numAttributes > + > + for i in range(0, notification.numAttributes): > + > + c_attribute = notification.changedAttributes[i] > + > + print '''- Attribute ID: %d - > + Attribute Type: (%d) %s''' % ( > + c_attribute.attributeId, > + c_attribute.attributeType, > + saNtf.eSaNtfValueTypeT.whatis(c_attribute.attributeType) > +) > + > + if c_attribute.oldAttributePresent: > + print ''' Old Attribute Present: Yes > + Old Attribute Value: %s''' % \ > + saNtf.unmarshalSaNtfValue(saAis.BYREF(c_attribute.oldAttributeValue), > + c_attribute.attributeType) > + else: > + print ' Old Attribute Present: No' > + > + print ' Attribute Value: %s' % \ > + > saNtf.unmarshalSaNtfValue(saAis.BYREF(c_attribute.newAttributeValue), > + c_attribute.attributeType) > + > + > +def print_state_change_notification(notification): > + ''' Prints the given state change notification''' > + > + header = notification.notificationHeader > + > + print '=== %s - State Change ===' % > SaTimeT_to_date_string(header.eventTime.contents.value) > + > + print_notification_header(header) > + > + print 'sourceIndicator = %s' % \ > + > saNtf.eSaNtfSourceIndicatorT.whatis(notification.sourceIndicator.contents.value) > + > + print > + > + i = 0 > + for c_state in notification.changedStates: > + > + if i == notification.numStateChanges: > + break > + > + i = i + 1 > + > + print '- State ID: %d -' % c_state.stateId > + > + if c_state.oldStatePresent: > + print ' Old State Present: Yes' > + print ' Old State: %s' % c_state.oldState > + else: > + print ' Old State Present: No' > + > + print ' New State: %s' % c_state.newState > + > + > +def print_security_alarm_notification(notification): > + ''' Prints the given security alarm notification''' > + > + header = notification.notificationHeader > + > + print '=== %s - Security Alarm ===' % > SaTimeT_to_date_string(header.eventTime.contents.value) > + > + print_notification_header(header) > + > + print'''probableCause = %s > +severity = %s > +Security Alarm Detector Type: %d > +Security Alarm Detector Value: %d > +Service User Type: %d > +Service User Value: %d > +Service Provider Type: %d > +Service Provider Value: %d > +''' % ( > + > saNtf.eSaNtfProbableCauseT.whatis(notification.probableCause.contents.value), > + saNtf.eSaNtfSeverityT.whatis(notification.severity.contents.value), > + notification.securityAlarmDetector.contents.valueType, > + > saNtf.unmarshalSaNtfValue(saAis.BYREF(notification.securityAlarmDetector.contents.value), > + > notification.securityAlarmDetector.contents.valueType), > + notification.serviceUser.contents.valueType, > + > saNtf.unmarshalSaNtfValue(saAis.BYREF(notification.serviceUser.contents.value), > + notification.serviceUser.contents.valueType), > + notification.serviceProvider.contents.valueType, > + > saNtf.unmarshalSaNtfValue(saAis.BYREF(notification.serviceProvider.contents.value), > + > notification.serviceProvider.contents.valueType) > +) > + > + > +def notification_received(subscription_id, c_p_notification): > + ''' Handle received notifications''' > + > + notification_type = c_p_notification.contents.notificationType > + > + print > + > + if notification_type == saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ALARM: > + notification = > c_p_notification.contents.notification.alarmNotification > + > + print_alarm_notification(notification) > + > + elif notification_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_OBJECT_CREATE_DELETE: > + notification = > c_p_notification.contents.notification.objectCreateDeleteNotification > + > + print_object_create_delete_notification(notification) > + > + elif notification_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ATTRIBUTE_CHANGE: > + notification = > c_p_notification.contents.notification.attributeChangeNotification > + > + print_attribute_change_notification(notification) > + > + elif notification_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_STATE_CHANGE: > + notification = > c_p_notification.contents.notification.stateChangeNotification > + > + print_state_change_notification(notification) > + > + elif notification_type == > saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_SECURITY_ALARM: > + notification = > c_p_notification.contents.notification.securityAlarmNotification > + > + print_security_alarm_notification(notification) > + > + > +if __name__ == '__main__': > + > + # Parse the parameters > + parser = argparse.ArgumentParser( > + description='ntfsubscribe is a SAF NTF client used to subscribe for > all incoming notifications.') > + > + parser.add_argument('--timeout', '-t', metavar='TIME', > + default=1, > + help='timeout (sec) waiting for notification') > + > + parser.add_argument('--alarm', '-a', > + dest='alarm', action='store_true', > + help='subscribe for only alarm notifications') > + > + parser.add_argument('--objectCreateDelete', '-o', > + dest='object_create_delete', action='store_true', > + help='subscribe for only objectCreateDelete > notifications') > + > + parser.add_argument('--attributeChange', '-c', > + dest='attribute_change', action='store_true', > + help='subscribe for only attributeChange > notifications') > + > + parser.add_argument('--stateChange', '-s', > + dest='state_change', action='store_true', > + help='subscribe for only stateChange notifications') > + > + parser.add_argument('--securityAlarm', '-y', > + dest='security_alarm', action='store_true', > + help='subscribe for only securityAlarm > notifications') > + > + args = parser.parse_args() > + > + print args.timeout > + > + # Initialize the NTF library > + ntf.initialize(notification_callback=notification_received) > + > + # Subscribe for notifications > + subscriptions = [] > + > + if args.object_create_delete: > + > subscriptions.append(saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_OBJECT_CREATE_DELETE) > + > + if args.alarm: > + subscriptions.append(saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ALARM) > + > + if args.attribute_change: > + > subscriptions.append(saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_ATTRIBUTE_CHANGE) > + > + if args.state_change: > + > subscriptions.append(saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_STATE_CHANGE) > + > + if args.security_alarm: > + > subscriptions.append(saNtf.eSaNtfNotificationTypeT.SA_NTF_TYPE_SECURITY_ALARM) > + > + if subscriptions == []: > + ntf.subscribe_for_notifications() > + else: > + ntf.subscribe_for_notifications(notification_types=subscriptions) > + > + # Get selection object for the implementer > + selection_object = ntf.SELECTION_OBJECT.value > + > + # Wait for next OI event or one second timeout > + inputs = [selection_object] > + outputs = [] > + > + # Loop and wait for notifications > + while True: > + > + readable, writable, exceptional = \ > + select.select(inputs, outputs, inputs, args.timeout) > + > + if selection_object in readable: > + ntf.dispatch(saAis.eSaDispatchFlagsT.SA_DISPATCH_ALL) ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel