/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
 *
 * $Id$
 */
/** \page MFD helper for snmpNotifyFilterTable
 *
 * \section intro Introduction
 * Introductory text.
 *
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "snmpNotifyFilterTable.h"

#include <net-snmp/agent/mib_modules.h>

#include "snmpNotifyFilterTable_interface.h"

const oid       snmpNotifyFilterTable_oid[] =
    { SNMPNOTIFYFILTERTABLE_OID };
const int       snmpNotifyFilterTable_oid_size =
OID_LENGTH(snmpNotifyFilterTable_oid);

snmpNotifyFilterTable_registration snmpNotifyFilterTable_user_context;
static snmpNotifyFilterTable_registration *snmpNotifyFilterTable_user_context_p;

void            initialize_table_snmpNotifyFilterTable(void);
void            shutdown_table_snmpNotifyFilterTable(void);


/**
 * Initializes the snmpNotifyFilterTable module
 */
void
init_snmpNotifyFilterTable(void)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:init_snmpNotifyFilterTable",
                "called\n"));

    /*
     * TODO:300:o: Perform snmpNotifyFilterTable one-time module initialization.
     */

    /*
     * here we initialize all the tables we're planning on supporting
     */
    if (should_init("snmpNotifyFilterTable"))
        initialize_table_snmpNotifyFilterTable();

}                               /* init_snmpNotifyFilterTable */

/**
 * Shut-down the snmpNotifyFilterTable module (agent is exiting)
 */
void
shutdown_snmpNotifyFilterTable(void)
{
    if (should_init("snmpNotifyFilterTable"))
        shutdown_table_snmpNotifyFilterTable();

}

/**
 * Initialize the table snmpNotifyFilterTable 
 *    (Define its contents and how it's structured)
 */
void
initialize_table_snmpNotifyFilterTable(void)
{
    u_long          flags;

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:initialize_table_snmpNotifyFilterTable", "called\n"));

    /*
     * TODO:301:o: Perform snmpNotifyFilterTable one-time table initialization.
     */

    /*
     * TODO:302:o: |->Initialize snmpNotifyFilterTable user context
     * if you'd like to pass in a pointer to some data for this
     * table, allocate or set it up here.
     */
    /*
     * a netsnmp_data_list is a simple way to store void pointers. A simple
     * string token is used to add, find or remove pointers.
     */
    snmpNotifyFilterTable_user_context_p =
        netsnmp_create_data_list("snmpNotifyFilterTable", NULL, NULL);

    /*
     * No support for any flags yet, but in the future you would
     * set any flags here.
     */
    flags = 0;

    /*
     * call interface initialization code
     */
    _snmpNotifyFilterTable_initialize_interface
	(snmpNotifyFilterTable_user_context_p, flags);
}                               /* initialize_table_snmpNotifyFilterTable */

/**
 * Shutdown the table snmpNotifyFilterTable 
 */
void
shutdown_table_snmpNotifyFilterTable(void)
{
    /*
     * call interface shutdown code
     */
    _snmpNotifyFilterTable_shutdown_interface
        (snmpNotifyFilterTable_user_context_p);
    netsnmp_free_all_list_data(snmpNotifyFilterTable_user_context_p);
    snmpNotifyFilterTable_user_context_p = NULL;
}

/**
 * extra context initialization (eg default values)
 *
 * @param rowreq_ctx    : row request context
 * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
 *
 * @retval MFD_SUCCESS  : no errors
 * @retval MFD_ERROR    : error (context allocate will fail)
 */
int
snmpNotifyFilterTable_rowreq_ctx_init(snmpNotifyFilterTable_rowreq_ctx *
                                      rowreq_ctx, void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra snmpNotifyFilterTable rowreq initialization. (eg DEFVALS)
     */
    /*
     * strings and oids are hard to handle automagically.
     * so all we've got for you is a hint:
     *
     * memcpy(rowreq_ctx->data.snmpNotifyFilterMask, 0,
     *        len(0) * sizeof(snmpNotifyFilterMask[0]);
     */

    rowreq_ctx->data.snmpNotifyFilterType = SNMPNOTIFYFILTERTYPE_INCLUDED;

    rowreq_ctx->data.snmpNotifyFilterStorageType = STORAGETYPE_NONVOLATILE;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_rowreq_ctx_init */

/**
 * extra context cleanup
 * @param  rowreq_ctx
 */
void
snmpNotifyFilterTable_rowreq_ctx_cleanup(snmpNotifyFilterTable_rowreq_ctx *
                                         rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra snmpNotifyFilterTable rowreq cleanup.
     */
}                               /* snmpNotifyFilterTable_rowreq_ctx_cleanup */

/************************************************************
 * the *_should_save routine is called to determine if a row
 * should be stored persistently.
 *
 * Note that this is not a 'dirty' check (i.e. if a row has changed),
 * but a check for volatile rows that should not be saved between
 * restarts.
 * @param rowreq_ctx
 * @retval  1 if the row should be stored
 * @retval  0 if the row should not be stored
 */
int
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    snmpNotifyFilterTable_container_should_save
    (snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx) {
    if (SNMP_STORAGE_VOLATILE ==
        rowreq_ctx->data.snmpNotifyFilterStorageType)
        return 0;

    return 1;                   /* save the row */
}

/**
 * pre-request callback
 *
 * @param user_context
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_ERROR                : other error
 */
int
snmpNotifyFilterTable_pre_request(snmpNotifyFilterTable_registration *
                                  user_context)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_pre_request", "called\n"));

    /*
     * TODO:510:o: Perform snmpNotifyFilterTable pre-request actions.
     */

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_pre_request */

/**
 * post-request callback
 *
 * Note:
 *   New rows have been inserted into the container, and
 *   deleted rows have been removed from the container and
 *   released.
 * @param user_context
 * @param rc : MFD_SUCCESS if all requests succeeded
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : other error (ignored)
 */
int
snmpNotifyFilterTable_post_request(snmpNotifyFilterTable_registration *
                                   user_context, int rc)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_post_request", "called\n"));

    /*
     * TODO:511:o: Perform snmpNotifyFilterTable post-request actions.
     */

    /*
     * check to set if any rows were changed.
     */
    if (snmpNotifyFilterTable_dirty_get()) {
        /*
         * check if request was successful. If so, this would be
         * a good place to save data to its persistent store.
         */
        if (MFD_SUCCESS == rc) {
            /*
             * notify library to save changed rows
             */
            snmp_store_needed(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                             NETSNMP_DS_LIB_APPTYPE));
        }

        snmpNotifyFilterTable_dirty_set(0);     /* clear table dirty flag */
    }

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** Table snmpNotifyFilterTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterTable is subid 3 of snmpNotifyObjects.
 * Its status is Current.
 * OID: .1.3.6.1.6.3.13.1.3, length: 9
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement snmpNotifyFilterTable data context functions.
 */


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param snmpNotifyFilterProfileName_val_ptr
 * @param snmpNotifyFilterProfileName_val_ptr_len
 * @param snmpNotifyFilterSubtree_val_ptr
 * @param snmpNotifyFilterSubtree_val_ptr_len
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This convenience function is useful for setting all the MIB index
 *  components with a single function call. It is assume that the C values
 *  have already been mapped from their native/rawformat to the MIB format.
 */
int
snmpNotifyFilterTable_indexes_set_tbl_idx(snmpNotifyFilterTable_mib_index *
                                          tbl_idx, char
                                          *snmpNotifyFilterProfileName_val_ptr,
                                          size_t
                                          snmpNotifyFilterProfileName_val_ptr_len,
                                          oid *
                                          snmpNotifyFilterSubtree_val_ptr,
                                          size_t
                                          snmpNotifyFilterSubtree_val_ptr_len)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_indexes_set_tbl_idx", "called\n"));

    /*
     * snmpNotifyFilterProfileName(1)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
     */
    tbl_idx->snmpNotifyFilterProfileName_len = sizeof(tbl_idx->snmpNotifyFilterProfileName) / sizeof(tbl_idx->snmpNotifyFilterProfileName[0]);  /* max length */
    /*
     * make sure there is enough space for snmpNotifyFilterProfileName data
     */
    if ((NULL == tbl_idx->snmpNotifyFilterProfileName) ||
        (tbl_idx->snmpNotifyFilterProfileName_len <
         (snmpNotifyFilterProfileName_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->snmpNotifyFilterProfileName_len =
        snmpNotifyFilterProfileName_val_ptr_len;
    memcpy(tbl_idx->snmpNotifyFilterProfileName,
           snmpNotifyFilterProfileName_val_ptr,
           snmpNotifyFilterProfileName_val_ptr_len *
           sizeof(snmpNotifyFilterProfileName_val_ptr[0]));

    /*
     * snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
     */
    tbl_idx->snmpNotifyFilterSubtree_len = sizeof(tbl_idx->snmpNotifyFilterSubtree) / sizeof(tbl_idx->snmpNotifyFilterSubtree[0]);      /* max length */
    /*
     * make sure there is enough space for snmpNotifyFilterSubtree data
     */
    if ((NULL == tbl_idx->snmpNotifyFilterSubtree) ||
        (tbl_idx->snmpNotifyFilterSubtree_len <
         (snmpNotifyFilterSubtree_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->snmpNotifyFilterSubtree_len =
        snmpNotifyFilterSubtree_val_ptr_len;
    memcpy(tbl_idx->snmpNotifyFilterSubtree,
           snmpNotifyFilterSubtree_val_ptr,
           snmpNotifyFilterSubtree_val_ptr_len *
           sizeof(snmpNotifyFilterSubtree_val_ptr[0]));


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param rowreq_ctx the row context that needs updated indexes
 * @param snmpNotifyFilterProfileName_val_ptr
 * @param snmpNotifyFilterProfileName_val_ptr_len
 * @param snmpNotifyFilterSubtree_val_ptr
 * @param snmpNotifyFilterSubtree_val_ptr_len
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This function sets the mib indexs, then updates the oid indexs
 *  from the mib index.
 */
int
snmpNotifyFilterTable_indexes_set(snmpNotifyFilterTable_rowreq_ctx *
                                  rowreq_ctx, char
                                  *snmpNotifyFilterProfileName_val_ptr,
                                  size_t
                                  snmpNotifyFilterProfileName_val_ptr_len,
                                  oid * snmpNotifyFilterSubtree_val_ptr,
                                  size_t
                                  snmpNotifyFilterSubtree_val_ptr_len)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        snmpNotifyFilterTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                                  snmpNotifyFilterProfileName_val_ptr,
                                                  snmpNotifyFilterProfileName_val_ptr_len,
                                                  snmpNotifyFilterSubtree_val_ptr,
                                                  snmpNotifyFilterSubtree_val_ptr_len))
        return MFD_ERROR;

    /*
     * convert mib index to oid index
     */
    rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
    if (0 != snmpNotifyFilterTable_index_to_oid(&rowreq_ctx->oid_idx,
                                                &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_indexes_set */


/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterMask
 * snmpNotifyFilterMask is subid 2 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.2
 * Description:
The bit mask which, in combination with the corresponding
         instance of snmpNotifyFilterSubtree, defines a family of
         subtrees which are included in or excluded from the
         filter profile.

         Each bit of this bit mask corresponds to a
         sub-identifier of snmpNotifyFilterSubtree, with the
         most significant bit of the i-th octet of this octet
         string value (extended if necessary, see below)
         corresponding to the (8*i - 7)-th sub-identifier, and
         the least significant bit of the i-th octet of this
         octet string corresponding to the (8*i)-th
         sub-identifier, where i is in the range 1 through 16.

         Each bit of this bit mask specifies whether or not
         the corresponding sub-identifiers must match when
         determining if an OBJECT IDENTIFIER matches this
         family of filter subtrees; a '1' indicates that an
         exact match must occur; a '0' indicates 'wild card',
         i.e., any sub-identifier value matches.

         Thus, the OBJECT IDENTIFIER X of an object instance
         is contained in a family of filter subtrees if, for
         each sub-identifier of the value of
         snmpNotifyFilterSubtree, either:

           the i-th bit of snmpNotifyFilterMask is 0, or

           the i-th sub-identifier of X is equal to the i-th
           sub-identifier of the value of
           snmpNotifyFilterSubtree.

         If the value of this bit mask is M bits long and
         there are more than M sub-identifiers in the
         corresponding instance of snmpNotifyFilterSubtree,
         then the bit mask is extended with 1's to be the
         required length.

         Note that when the value of this object is the
         zero-length string, this extension rule results in
         a mask of all-1's being used (i.e., no 'wild card'),
         and the family of filter subtrees is the one
         subtree uniquely identified by the corresponding
         instance of snmpNotifyFilterSubtree.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 1      hashint   0
 *   settable   1
 *   defval: 0
 *
 * Ranges:  0 - 16;
 *
 * Its syntax is OCTETSTR (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 16)
 */
/**
 * Extract the current value of the snmpNotifyFilterMask data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterMask_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param snmpNotifyFilterMask_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by snmpNotifyFilterMask.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*snmpNotifyFilterMask_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update snmpNotifyFilterMask_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
snmpNotifyFilterMask_get(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx,
                         char **snmpNotifyFilterMask_val_ptr_ptr,
                         size_t * snmpNotifyFilterMask_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != snmpNotifyFilterMask_val_ptr_ptr)
                   && (NULL != *snmpNotifyFilterMask_val_ptr_ptr));
    netsnmp_assert(NULL != snmpNotifyFilterMask_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterMask_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the snmpNotifyFilterMask data.
     * copy (* snmpNotifyFilterMask_val_ptr_ptr ) data and (* snmpNotifyFilterMask_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    /*
     * make sure there is enough space for snmpNotifyFilterMask data
     */
    if ((NULL == (*snmpNotifyFilterMask_val_ptr_ptr)) ||
        ((*snmpNotifyFilterMask_val_ptr_len_ptr) <
         (rowreq_ctx->data.snmpNotifyFilterMask_len *
          sizeof(rowreq_ctx->data.snmpNotifyFilterMask[0])))) {
        /*
         * allocate space for snmpNotifyFilterMask data
         */
        (*snmpNotifyFilterMask_val_ptr_ptr) = (char*)
            malloc(rowreq_ctx->data.snmpNotifyFilterMask_len *
                   sizeof(rowreq_ctx->data.snmpNotifyFilterMask[0]));
        if (NULL == (*snmpNotifyFilterMask_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*snmpNotifyFilterMask_val_ptr_len_ptr) =
        rowreq_ctx->data.snmpNotifyFilterMask_len *
        sizeof(rowreq_ctx->data.snmpNotifyFilterMask[0]);
    memcpy((*snmpNotifyFilterMask_val_ptr_ptr),
           rowreq_ctx->data.snmpNotifyFilterMask,
           rowreq_ctx->data.snmpNotifyFilterMask_len *
           sizeof(rowreq_ctx->data.snmpNotifyFilterMask[0]));

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterMask_get */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterType
 * snmpNotifyFilterType is subid 3 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.3
 * Description:
This object indicates whether the family of filter subtrees
         defined by this entry are included in or excluded from a
         filter.  A more detailed discussion of the use of this
         object can be found in section 6. of [SNMP-APPL].
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: included
 *
 * Enum range: 2/8. Values:  included(1), excluded(2)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the snmpNotifyFilterType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterType_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
snmpNotifyFilterType_get(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx,
                         u_long * snmpNotifyFilterType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != snmpNotifyFilterType_val_ptr);


    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterType_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the snmpNotifyFilterType data.
     * copy (* snmpNotifyFilterType_val_ptr ) from rowreq_ctx->data
     */
    (*snmpNotifyFilterType_val_ptr) =
        rowreq_ctx->data.snmpNotifyFilterType;

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterType_get */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterStorageType
 * snmpNotifyFilterStorageType is subid 4 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.4
 * Description:
The storage type for this conceptual row.
         Conceptual rows having the value 'permanent' need not

         allow write-access to any columnar objects in the row.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: nonVolatile
 *
 * Enum range: 4/8. Values:  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
 *
 * Its syntax is StorageType (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the snmpNotifyFilterStorageType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterStorageType_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
snmpNotifyFilterStorageType_get(snmpNotifyFilterTable_rowreq_ctx *
                                rowreq_ctx,
                                u_long *
                                snmpNotifyFilterStorageType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != snmpNotifyFilterStorageType_val_ptr);


    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterStorageType_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the snmpNotifyFilterStorageType data.
     * copy (* snmpNotifyFilterStorageType_val_ptr ) from rowreq_ctx->data
     */
    (*snmpNotifyFilterStorageType_val_ptr) =
        rowreq_ctx->data.snmpNotifyFilterStorageType;

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterStorageType_get */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterRowStatus
 * snmpNotifyFilterRowStatus is subid 5 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.5
 * Description:
The status of this conceptual row.

         To create a row in this table, a manager must
         set this object to either createAndGo(4) or
         createAndWait(5).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * Its syntax is RowStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the snmpNotifyFilterRowStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterRowStatus_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
snmpNotifyFilterRowStatus_get(snmpNotifyFilterTable_rowreq_ctx *
                              rowreq_ctx,
                              u_long * snmpNotifyFilterRowStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != snmpNotifyFilterRowStatus_val_ptr);

    (*snmpNotifyFilterRowStatus_val_ptr) =
        rowreq_ctx->data.snmpNotifyFilterRowStatus;

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterRowStatus_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** Table snmpNotifyFilterTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterTable is subid 3 of snmpNotifyObjects.
 * Its status is Current.
 * OID: .1.3.6.1.6.3.13.1.3, length: 9
 */
    /*
     * NOTE: if you update this chart, please update the versions in
     *       local/mib2c-conf.d/parent-set.m2i
     *       agent/mibgroup/helpers/baby_steps.c
     * while you're at it.
     */
    /*
     ***********************************************************************
     * Baby Steps Flow Chart (2004.06.05)                                  *
     *                                                                     *
     * +--------------+    +================+    U = unconditional path    *
     * |optional state|    ||required state||    S = path for success      *
     * +--------------+    +================+    E = path for error        *
     ***********************************************************************
     *
     *                        +--------------+
     *                        |     pre      |
     *                        |   request    |
     *                        +--------------+
     *                               | U
     * +-------------+        +==============+
     * |    row    |f|<-------||  object    ||
     * |  create   |1|      E ||  lookup    ||
     * +-------------+        +==============+
     *     E |   | S                 | S
     *       |   +------------------>|
     *       |                +==============+
     *       |              E ||   check    ||
     *       |<---------------||   values   ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |       +<-------||   undo     ||
     *       |       |      E ||   setup    ||
     *       |       |        +==============+
     *       |       |               | S
     *       |       |        +==============+
     *       |       |        ||    set     ||-------------------------->+
     *       |       |        ||   value    || E                         |
     *       |       |        +==============+                           |
     *       |       |               | S                                 |
     *       |       |        +--------------+                           |
     *       |       |        |    check     |-------------------------->|
     *       |       |        |  consistency | E                         |
     *       |       |        +--------------+                           |
     *       |       |               | S                                 |
     *       |       |        +==============+         +==============+  |
     *       |       |        ||   commit   ||-------->||     undo   ||  |
     *       |       |        ||            || E       ||    commit  ||  |
     *       |       |        +==============+         +==============+  |
     *       |       |               | S                     U |<--------+
     *       |       |        +--------------+         +==============+
     *       |       |        | irreversible |         ||    undo    ||
     *       |       |        |    commit    |         ||     set    ||
     *       |       |        +--------------+         +==============+
     *       |       |               | U                     U |
     *       |       +-------------->|<------------------------+
     *       |                +==============+
     *       |                ||   undo     ||
     *       |                ||  cleanup   ||
     *       |                +==============+
     *       +---------------------->| U
     *                               |
     *                          (err && f1)------------------->+
     *                               |                         |
     *                        +--------------+         +--------------+
     *                        |    post      |<--------|      row     |
     *                        |   request    |       U |    release   |
     *                        +--------------+         +--------------+
     *
     */

/**
 * Setup up context with information needed to undo a set request.
 *
 * This function will be called before the individual node undo setup
 * functions are called. If you need to do any undo setup that is not
 * related to a specific column, you can do it here.
 *
 * Note that the undo context has been allocated with
 * snmpNotifyFilterTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * snmpNotifyFilterTable_rowreq_ctx_init().
 * Note that an individual node's undo_setup function will only be called
 * if that node is being set to a new value.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in the node's undo_setup
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
snmpNotifyFilterTable_undo_setup(snmpNotifyFilterTable_rowreq_ctx *
                                 rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_undo_setup", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> Setup snmpNotifyFilterTable undo.
     * set up snmpNotifyFilterTable undo information, in preparation for a set.
     * Undo storage is in (* snmpNotifyFilterRowStatus_val_ptr )*
     */

    return rc;
}                               /* snmpNotifyFilterTable_undo_setup */

/**
 * Undo a set request.
 *
 * This function will be called before the individual node undo
 * functions are called. If you need to do any undo that is not
 * related to a specific column, you can do it here.
 *
 * Note that an individual node's undo function will only be called
 * if that node is being set to a new value.
 *
 * If there is anything  specific to a particular column (e.g. releasing
 * memory for a string), you should do that setup in the node's undo
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
snmpNotifyFilterTable_undo(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_undo",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> snmpNotifyFilterTable undo.
     * snmpNotifyFilterTable undo information, in response to a failed set.
     * Undo storage is in (* snmpNotifyFilterRowStatus_val_ptr )*
     */

    return rc;
}                               /* snmpNotifyFilterTable_undo_setup */

/**
 * Cleanup up context undo information.
 *
 * This function will be called after set/commit processing. If you
 * allocated any resources in undo_setup, this is the place to release
 * those resources.
 *
 * This function is called regardless of the success or failure of the set
 * request. If you need to perform different steps for cleanup depending
 * on success or failure, you can add a flag to the rowreq_ctx.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
snmpNotifyFilterTable_undo_cleanup(snmpNotifyFilterTable_rowreq_ctx *
                                   rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_undo_cleanup", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:452:M: |-> Cleanup snmpNotifyFilterTable undo.
     * Undo storage is in (* snmpNotifyFilterRowStatus_val_ptr )*
     */

    return rc;
}                               /* snmpNotifyFilterTable_undo_cleanup */

/**
 * commit new values.
 *
 * At this point, you should have done everything you can to ensure that
 * this commit will not fail.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * snmpNotifyFilterTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
snmpNotifyFilterTable_commit(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_commit", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * commit snmpNotifyFilterTable data
     */

    /*
     * if we successfully commited this row, set the dirty flag.
     */
    rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;

    return rc;
}                               /* snmpNotifyFilterTable_commit */

/**
 * undo commit new values.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * snmpNotifyFilterTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
snmpNotifyFilterTable_undo_commit(snmpNotifyFilterTable_rowreq_ctx *
                                  rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_undo_commit", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:485:M: |-> Undo snmpNotifyFilterTable commit.
     * check the column's flag in rowreq_ctx->column_set_flags to see
     * if it was set during commit, then undo it.
     *
     * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
     */


    /*
     * if we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* snmpNotifyFilterTable_undo_commit */

/*
 * TODO:440:M: Implement snmpNotifyFilterTable node value checks.
 * TODO:450:M: Implement snmpNotifyFilterTable undo functions.
 * TODO:460:M: Implement snmpNotifyFilterTable set functions.
 * TODO:480:M: Implement snmpNotifyFilterTable commit functions.
 */
/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterMask
 * snmpNotifyFilterMask is subid 2 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.2
 * Description:
The bit mask which, in combination with the corresponding
         instance of snmpNotifyFilterSubtree, defines a family of
         subtrees which are included in or excluded from the
         filter profile.

         Each bit of this bit mask corresponds to a
         sub-identifier of snmpNotifyFilterSubtree, with the
         most significant bit of the i-th octet of this octet
         string value (extended if necessary, see below)
         corresponding to the (8*i - 7)-th sub-identifier, and
         the least significant bit of the i-th octet of this
         octet string corresponding to the (8*i)-th
         sub-identifier, where i is in the range 1 through 16.

         Each bit of this bit mask specifies whether or not
         the corresponding sub-identifiers must match when
         determining if an OBJECT IDENTIFIER matches this
         family of filter subtrees; a '1' indicates that an
         exact match must occur; a '0' indicates 'wild card',
         i.e., any sub-identifier value matches.

         Thus, the OBJECT IDENTIFIER X of an object instance
         is contained in a family of filter subtrees if, for
         each sub-identifier of the value of
         snmpNotifyFilterSubtree, either:

           the i-th bit of snmpNotifyFilterMask is 0, or

           the i-th sub-identifier of X is equal to the i-th
           sub-identifier of the value of
           snmpNotifyFilterSubtree.

         If the value of this bit mask is M bits long and
         there are more than M sub-identifiers in the
         corresponding instance of snmpNotifyFilterSubtree,
         then the bit mask is extended with 1's to be the
         required length.

         Note that when the value of this object is the
         zero-length string, this extension rule results in
         a mask of all-1's being used (i.e., no 'wild card'),
         and the family of filter subtrees is the one
         subtree uniquely identified by the corresponding
         instance of snmpNotifyFilterSubtree.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 1      hashint   0
 *   settable   1
 *   defval: 0
 *
 * Ranges:  0 - 16;
 *
 * Its syntax is OCTETSTR (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 16)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterMask_val_ptr
 *        A char containing the new value.
 * @param snmpNotifyFilterMask_val_ptr_len
 *        The size (in bytes) of the data pointed to by snmpNotifyFilterMask_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * snmpNotifyFilterTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *    The length is < sizeof(rowreq_ctx->data.snmpNotifyFilterMask).
 *    The length is in (one of) the range set(s):  0 - 16
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
snmpNotifyFilterMask_check_value(snmpNotifyFilterTable_rowreq_ctx *
                                 rowreq_ctx,
                                 char *snmpNotifyFilterMask_val_ptr,
                                 size_t snmpNotifyFilterMask_val_ptr_len)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterMask_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != snmpNotifyFilterMask_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid snmpNotifyFilterMask value.
     */

    return MFD_SUCCESS;         /* snmpNotifyFilterMask value not illegal */
}                               /* snmpNotifyFilterMask_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * snmpNotifyFilterTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
snmpNotifyFilterMask_undo_setup(snmpNotifyFilterTable_rowreq_ctx *
                                rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterMask_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup snmpNotifyFilterMask undo.
     */
    /*
     * copy snmpNotifyFilterMask and snmpNotifyFilterMask_len data
     * set rowreq_ctx->undo->snmpNotifyFilterMask from rowreq_ctx->data.snmpNotifyFilterMask
     */
    memcpy(rowreq_ctx->undo->snmpNotifyFilterMask,
           rowreq_ctx->data.snmpNotifyFilterMask,
           (rowreq_ctx->data.snmpNotifyFilterMask_len *
            sizeof(rowreq_ctx->undo->snmpNotifyFilterMask[0])));
    rowreq_ctx->undo->snmpNotifyFilterMask_len =
        rowreq_ctx->data.snmpNotifyFilterMask_len;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterMask_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param snmpNotifyFilterMask_val_ptr
 *        A char containing the new value.
 * @param snmpNotifyFilterMask_val_ptr_len
 *        The size (in bytes) of the data pointed to by snmpNotifyFilterMask_val_ptr
 */
int
snmpNotifyFilterMask_set(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx,
                         char *snmpNotifyFilterMask_val_ptr,
                         size_t snmpNotifyFilterMask_val_ptr_len)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterMask_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != snmpNotifyFilterMask_val_ptr);

    /*
     * TODO:461:M: |-> Set snmpNotifyFilterMask value.
     * set snmpNotifyFilterMask value in rowreq_ctx->data
     */
    memcpy(rowreq_ctx->data.snmpNotifyFilterMask,
           snmpNotifyFilterMask_val_ptr, snmpNotifyFilterMask_val_ptr_len);
    /** convert bytes to number of char */
    rowreq_ctx->data.snmpNotifyFilterMask_len =
        snmpNotifyFilterMask_val_ptr_len /
        sizeof(snmpNotifyFilterMask_val_ptr[0]);

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterMask_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
snmpNotifyFilterMask_undo(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterMask_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up snmpNotifyFilterMask undo.
     */
    /*
     * copy snmpNotifyFilterMask and snmpNotifyFilterMask_len data
     * set rowreq_ctx->data.snmpNotifyFilterMask from rowreq_ctx->undo->snmpNotifyFilterMask
     */
    memcpy(rowreq_ctx->data.snmpNotifyFilterMask,
           rowreq_ctx->undo->snmpNotifyFilterMask,
           (rowreq_ctx->undo->snmpNotifyFilterMask_len *
            sizeof(rowreq_ctx->data.snmpNotifyFilterMask[0])));
    rowreq_ctx->data.snmpNotifyFilterMask_len =
        rowreq_ctx->undo->snmpNotifyFilterMask_len;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterMask_undo */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterType
 * snmpNotifyFilterType is subid 3 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.3
 * Description:
This object indicates whether the family of filter subtrees
         defined by this entry are included in or excluded from a
         filter.  A more detailed discussion of the use of this
         object can be found in section 6. of [SNMP-APPL].
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: included
 *
 * Enum range: 2/8. Values:  included(1), excluded(2)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterType_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * snmpNotifyFilterTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  included(1), excluded(2)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
snmpNotifyFilterType_check_value(snmpNotifyFilterTable_rowreq_ctx *
                                 rowreq_ctx,
                                 u_long snmpNotifyFilterType_val)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterType_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid snmpNotifyFilterType value.
     */

    return MFD_SUCCESS;         /* snmpNotifyFilterType value not illegal */
}                               /* snmpNotifyFilterType_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * snmpNotifyFilterTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
snmpNotifyFilterType_undo_setup(snmpNotifyFilterTable_rowreq_ctx *
                                rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterType_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup snmpNotifyFilterType undo.
     */
    /*
     * copy snmpNotifyFilterType data
     * set rowreq_ctx->undo->snmpNotifyFilterType from rowreq_ctx->data.snmpNotifyFilterType
     */
    rowreq_ctx->undo->snmpNotifyFilterType =
        rowreq_ctx->data.snmpNotifyFilterType;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterType_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param snmpNotifyFilterType_val
 *        A long containing the new value.
 */
int
snmpNotifyFilterType_set(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx,
                         u_long snmpNotifyFilterType_val)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterType_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set snmpNotifyFilterType value.
     * set snmpNotifyFilterType value in rowreq_ctx->data
     */
    rowreq_ctx->data.snmpNotifyFilterType = snmpNotifyFilterType_val;

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterType_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
snmpNotifyFilterType_undo(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterType_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up snmpNotifyFilterType undo.
     */
    /*
     * copy snmpNotifyFilterType data
     * set rowreq_ctx->data.snmpNotifyFilterType from rowreq_ctx->undo->snmpNotifyFilterType
     */
    rowreq_ctx->data.snmpNotifyFilterType =
        rowreq_ctx->undo->snmpNotifyFilterType;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterType_undo */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterStorageType
 * snmpNotifyFilterStorageType is subid 4 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.4
 * Description:
The storage type for this conceptual row.
         Conceptual rows having the value 'permanent' need not

         allow write-access to any columnar objects in the row.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: nonVolatile
 *
 * Enum range: 4/8. Values:  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
 *
 * Its syntax is StorageType (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterStorageType_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * snmpNotifyFilterTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
snmpNotifyFilterStorageType_check_value(snmpNotifyFilterTable_rowreq_ctx *
                                        rowreq_ctx,
                                        u_long
                                        snmpNotifyFilterStorageType_val)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterStorageType_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid snmpNotifyFilterStorageType value.
     */

    return MFD_SUCCESS;         /* snmpNotifyFilterStorageType value not illegal */
}                               /* snmpNotifyFilterStorageType_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * snmpNotifyFilterTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
snmpNotifyFilterStorageType_undo_setup(snmpNotifyFilterTable_rowreq_ctx *
                                       rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterStorageType_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup snmpNotifyFilterStorageType undo.
     */
    /*
     * copy snmpNotifyFilterStorageType data
     * set rowreq_ctx->undo->snmpNotifyFilterStorageType from rowreq_ctx->data.snmpNotifyFilterStorageType
     */
    rowreq_ctx->undo->snmpNotifyFilterStorageType =
        rowreq_ctx->data.snmpNotifyFilterStorageType;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterStorageType_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param snmpNotifyFilterStorageType_val
 *        A long containing the new value.
 */
int
snmpNotifyFilterStorageType_set(snmpNotifyFilterTable_rowreq_ctx *
                                rowreq_ctx,
                                u_long snmpNotifyFilterStorageType_val)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterStorageType_set", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set snmpNotifyFilterStorageType value.
     * set snmpNotifyFilterStorageType value in rowreq_ctx->data
     */
    rowreq_ctx->data.snmpNotifyFilterStorageType =
        snmpNotifyFilterStorageType_val;

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterStorageType_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
snmpNotifyFilterStorageType_undo(snmpNotifyFilterTable_rowreq_ctx *
                                 rowreq_ctx)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterStorageType_undo", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up snmpNotifyFilterStorageType undo.
     */
    /*
     * copy snmpNotifyFilterStorageType data
     * set rowreq_ctx->data.snmpNotifyFilterStorageType from rowreq_ctx->undo->snmpNotifyFilterStorageType
     */
    rowreq_ctx->data.snmpNotifyFilterStorageType =
        rowreq_ctx->undo->snmpNotifyFilterStorageType;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterStorageType_undo */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterRowStatus
 * snmpNotifyFilterRowStatus is subid 5 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.3.1.5
 * Description:
The status of this conceptual row.

         To create a row in this table, a manager must
         set this object to either createAndGo(4) or
         createAndWait(5).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * Its syntax is RowStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param snmpNotifyFilterRowStatus_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * snmpNotifyFilterTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
snmpNotifyFilterRowStatus_check_value(snmpNotifyFilterTable_rowreq_ctx *
                                      rowreq_ctx,
                                      u_long snmpNotifyFilterRowStatus_val)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterRowStatus_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid snmpNotifyFilterRowStatus value.
     */

    return MFD_SUCCESS;         /* snmpNotifyFilterRowStatus value not illegal */
}                               /* snmpNotifyFilterRowStatus_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (snmpNotifyFilterTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * snmpNotifyFilterTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
snmpNotifyFilterRowStatus_undo_setup(snmpNotifyFilterTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterRowStatus_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup snmpNotifyFilterRowStatus undo.
     */
    /*
     * copy snmpNotifyFilterRowStatus data
     * set rowreq_ctx->undo->snmpNotifyFilterRowStatus from rowreq_ctx->data.snmpNotifyFilterRowStatus
     */
    rowreq_ctx->undo->snmpNotifyFilterRowStatus =
        rowreq_ctx->data.snmpNotifyFilterRowStatus;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterRowStatus_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param snmpNotifyFilterRowStatus_val
 *        A long containing the new value.
 */
int
snmpNotifyFilterRowStatus_set(snmpNotifyFilterTable_rowreq_ctx *
                              rowreq_ctx,
                              u_long snmpNotifyFilterRowStatus_val)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterRowStatus_set", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set snmpNotifyFilterRowStatus value.
     * set snmpNotifyFilterRowStatus value in rowreq_ctx->data
     */
    rowreq_ctx->data.snmpNotifyFilterRowStatus =
        snmpNotifyFilterRowStatus_val;

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterRowStatus_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
snmpNotifyFilterRowStatus_undo(snmpNotifyFilterTable_rowreq_ctx *
                               rowreq_ctx)
{

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterRowStatus_undo", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up snmpNotifyFilterRowStatus undo.
     */
    /*
     * copy snmpNotifyFilterRowStatus data
     * set rowreq_ctx->data.snmpNotifyFilterRowStatus from rowreq_ctx->undo->snmpNotifyFilterRowStatus
     */
    rowreq_ctx->data.snmpNotifyFilterRowStatus =
        rowreq_ctx->undo->snmpNotifyFilterRowStatus;


    return MFD_SUCCESS;
}                               /* snmpNotifyFilterRowStatus_undo */

/**
 * check dependencies
 *
 * This is useful for for tables which have dependencies between columns
 * (or rows, or tables). For example, two columns allocating a percentage
 * of something add up 100%.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * snmpNotifyFilterTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @retval MFD_SUCCESS all the changes to the row are legal
 * @retval MFD_ERROR   one or more changes are not legal
 *
 * (see README-table-snmpNotifyFilterTable if you don't have dependencies)
 */
int
snmpNotifyFilterTable_check_dependencies(snmpNotifyFilterTable_rowreq_ctx *
                                         rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:snmpNotifyFilterTable_check_dependencies", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check snmpNotifyFilterTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    /*
     * check for valid StorageType transition (old, new)
     */
    rc = check_storage_transition(rowreq_ctx->undo->
                                  snmpNotifyFilterStorageType,
                                  rowreq_ctx->data.
                                  snmpNotifyFilterStorageType);
    if (MFD_SUCCESS != rc)
        return rc;

    /*
     * check RowStatus dependencies
     */
    if (rowreq_ctx->
        column_set_flags & COLUMN_SNMPNOTIFYFILTERROWSTATUS_FLAG) {
        /*
         * check for valid RowStatus transition (old, new)
         * (Note: move transition check to 
         *  to catch errors earlier)
         */
        rc = check_rowstatus_transition(rowreq_ctx->undo->
                                        snmpNotifyFilterRowStatus,
                                        rowreq_ctx->data.
                                        snmpNotifyFilterRowStatus);
        if (MFD_SUCCESS != rc)
            return rc;

        /*
         * row creation requirements
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            if (ROWSTATUS_DESTROY ==
                rowreq_ctx->data.snmpNotifyFilterRowStatus) {
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
            } else if (ROWSTATUS_CREATEANDGO ==
                       rowreq_ctx->data.snmpNotifyFilterRowStatus) {
                if ((rowreq_ctx->
                     column_set_flags &
                     SNMPNOTIFYFILTERTABLE_REQUIRED_COLS)
                    != SNMPNOTIFYFILTERTABLE_REQUIRED_COLS) {
                    DEBUGMSGTL(("snmpNotifyFilterTable",
                                "required columns missing (0x%0x != 0x%0x)\n",
                                rowreq_ctx->column_set_flags,
                                SNMPNOTIFYFILTERTABLE_REQUIRED_COLS));
                    return MFD_CANNOT_CREATE_NOW;
                }
                rowreq_ctx->data.snmpNotifyFilterRowStatus =
                    ROWSTATUS_ACTIVE;
            }
        } /* row creation */
        else {
            /*
             * row change requirements
             */
            /*
             * don't allow a destroy if any other value was changed, since
             * that might call data access routines with bad info.
             *
             * you may or may not require the row be notInService before it
             * can be destroyed.
             */
            if (ROWSTATUS_DESTROY ==
                rowreq_ctx->data.snmpNotifyFilterRowStatus) {
                if (rowreq_ctx->
                    column_set_flags &
                    ~COLUMN_SNMPNOTIFYFILTERROWSTATUS_FLAG) {
                    DEBUGMSGTL(("snmpNotifyFilterTable",
                                "destroy must be only varbind for row\n"));
                    return MFD_NOT_VALID_NOW;
                }
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;

            }                   /* row destroy */
        }                       /* row change */
    } else {
        /*
         * must have row status to create a row
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            DEBUGMSGTL(("snmpNotifyFilterTable",
                        "must use RowStatus to create rows\n"));
            return MFD_CANNOT_CREATE_NOW;
        }
    }                           /* row status not set */

    if (MFD_SUCCESS != rc)
        return rc;

    return rc;
}                               /* snmpNotifyFilterTable_check_dependencies */

/** @} */
/** @{ */
