/*
 * 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-features.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"

netsnmp_feature_require(check_storage_transition)

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 */

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