Hi Srikanth,

Thanks for coming back to these patches. There are some limitations in these 
that need improvement but I think it's good to push them as a base.

/ Johan

-----Original Message-----
From: Srikanth Revanuru [mailto:srikanth.revan...@oracle.com] 
Sent: den 7 april 2016 13:56
To: Johan Mårtensson O; Hans Nordebäck; mathi.naic...@oracle.com; Hung Duc 
Nguyen
Cc: opensaf-devel@lists.sourceforge.net
Subject: Re: [PATCH 1 of 1] pyosaf: Add NTF high-level bindings and sample 
applications [#1586]

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

Reply via email to