/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.iterate.conf 17695 2009-07-21 12:22:18Z dts12 $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "ccAuditLoggingCfgTable.h"

/* Typical data structure for a row entry */
struct ccAuditLoggingCfgTable_entry {
    /* Index values */
    char ccAuditLogsnmpv3UserName[255];
    size_t ccAuditLogsnmpv3UserName_len;
    in_addr_t ccAuditLogsnmpClientIpAddr;

    /* Column values */
    //char ccAuditLogsnmpv3UserName[255];
    //size_t ccAuditLogsnmpv3UserName_len;
    char old_ccAuditLogsnmpv3UserName[255];
    size_t old_ccAuditLogsnmpv3UserName_len;
    //in_addr_t ccAuditLogsnmpClientIpAddr;
    in_addr_t old_ccAuditLogsnmpClientIpAddr;
    long ccAuditLogRowStatus;

    /* Illustrate using a simple linked list */
    int   valid;
    struct ccAuditLoggingCfgTable_entry *next;
};

struct ccAuditLoggingCfgTable_entry  *ccAuditLoggingCfgTable_head = NULL;
//struct ccAuditLoggingCfgTable_entry          *table_row = ccAuditLoggingCfgTable_head;

struct ccAuditLoggingCfgTable_entry *
ccAuditLoggingCfgTable_createEntry(
                 char* ccAuditLogsnmpv3UserName,
                 size_t ccAuditLogsnmpv3UserName_len,
                 in_addr_t  ccAuditLogsnmpClientIpAddr);

/*
 * Function used from latest net-snmp version 
 */
	int
snmp_set_var_typed_integer(netsnmp_variable_list * newvar,
		u_char type, long val)
{
	newvar->type = type;
	return snmp_set_var_value(newvar, &val, sizeof(long));
}



/** Initializes the ccAuditLoggingCfgTable module */
void
init_ccAuditLoggingCfgTable(void)
{
  /* here we initialize all the tables we're planning on supporting */
    // snmp_log( LOG_ERR,"Entering-> Fun:%s Line:%d \n", __func__, __LINE__);
    initialize_table_ccAuditLoggingCfgTable();
    // snmp_log( LOG_ERR,"Exiting-> Fun:%s Line:%d \n", __func__, __LINE__);
}


//  # Determine the first/last column names

/** Initialize the ccAuditLoggingCfgTable table by defining its contents and how it's structured */
void
initialize_table_ccAuditLoggingCfgTable(void)
{
    const oid ccAuditLoggingCfgTable_oid[] = {1,3,6,1,4,1,388,11,2,2,11,10};
    const size_t ccAuditLoggingCfgTable_oid_len   = OID_LENGTH(ccAuditLoggingCfgTable_oid);
    netsnmp_handler_registration    *reg;
    netsnmp_iterator_info           *iinfo;
    netsnmp_table_registration_info *table_info;

    struct ccAuditLoggingCfgTable_entry *entry = NULL;

     snmp_log( LOG_ERR,"Entering-> Fun:%s Line:%d \n", __func__, __LINE__);

    DEBUGMSGTL(("ccAuditLoggingCfgTable:init", "initializing table ccAuditLoggingCfgTable\n"));

    reg = netsnmp_create_handler_registration("ccAuditLoggingCfgTable",     
		    			      ccAuditLoggingCfgTable_handler,  
				  	      ccAuditLoggingCfgTable_oid, 
					      ccAuditLoggingCfgTable_oid_len,
				              HANDLER_CAN_RWRITE);

    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes(table_info,
                           ASN_OCTET_STR,  /* index: ccAuditLogsnmpv3UserName */
                           ASN_IPADDRESS,  /* index: ccAuditLogsnmpClientIpAddr */
                           0);
    table_info->min_column = COLUMN_CCAUDITLOGSNMPV3USERNAME;
    table_info->max_column = COLUMN_CCAUDITLOGROWSTATUS;
    
    iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
    iinfo->get_first_data_point = ccAuditLoggingCfgTable_get_first_data_point;
    iinfo->get_next_data_point  = ccAuditLoggingCfgTable_get_next_data_point;
    iinfo->table_reginfo        = table_info;
    
    netsnmp_register_table_iterator( reg, iinfo );

    snmp_log( LOG_ERR,"Before Initialisation-> Fun:%s Line:%d \n", __func__, __LINE__);
    /* Initialise the contents of the table here */
    entry = ccAuditLoggingCfgTable_createEntry("sanjay", 7, 1111); 
    entry->ccAuditLogRowStatus = RS_CREATEANDGO;
    entry->valid = 1;
    snmp_log( LOG_ERR,"After Init and Exiting-> Fun:%s Line:%d \n", __func__, __LINE__);
}

/* create a new row in the (unsorted) table */
struct ccAuditLoggingCfgTable_entry *
ccAuditLoggingCfgTable_createEntry(
                 char* ccAuditLogsnmpv3UserName,
                 size_t ccAuditLogsnmpv3UserName_len,
                 in_addr_t  ccAuditLogsnmpClientIpAddr
                ) {
    struct ccAuditLoggingCfgTable_entry *entry;
    struct ccAuditLoggingCfgTable_entry *loop_entry;

    entry = SNMP_MALLOC_TYPEDEF(struct ccAuditLoggingCfgTable_entry);
    if (!entry)
        return NULL;

    memcpy(entry->ccAuditLogsnmpv3UserName, ccAuditLogsnmpv3UserName, ccAuditLogsnmpv3UserName_len);
    entry->ccAuditLogsnmpv3UserName_len = ccAuditLogsnmpv3UserName_len;
    entry->ccAuditLogsnmpClientIpAddr = ccAuditLogsnmpClientIpAddr;
#if 0
    entry->next = NULL;
    if(NULL == ccAuditLoggingCfgTable_head){
	ccAuditLoggingCfgTable_head = entry;
	snmp_log( LOG_ERR,"Head Entry -> UserName:%s \n", entry->ccAuditLogsnmpv3UserName);
    }
    else{ 
    	loop_entry = ccAuditLoggingCfgTable_head;
	while(NULL != loop_entry->next){
	    	snmp_log( LOG_ERR,"ADDING -> UserName:%s \n", loop_entry->ccAuditLogsnmpv3UserName);
		loop_entry = loop_entry->next;
	}
	loop_entry->next = entry;
    }
#endif
#if 1
    //snmp_log( LOG_ERR,"ADDING -> UserName:%s \n", loop_entry->ccAuditLogsnmpv3UserName);
    entry->next = ccAuditLoggingCfgTable_head;
    ccAuditLoggingCfgTable_head = entry;
#endif
    return entry;
}

/* remove a row from the table */
void
ccAuditLoggingCfgTable_removeEntry( struct ccAuditLoggingCfgTable_entry *entry ) {
    struct ccAuditLoggingCfgTable_entry *ptr, *prev;

    if (!entry)
        return;    /* Nothing to remove */

    for ( ptr  = ccAuditLoggingCfgTable_head, prev = NULL;
          ptr != NULL;
          prev = ptr, ptr = ptr->next ) {
        if ( ptr == entry )
            break;
    }
    if ( !ptr )
        return;    /* Can't find it */

    if ( prev == NULL )
        ccAuditLoggingCfgTable_head = ptr->next;
    else
        prev->next = ptr->next;

    SNMP_FREE( entry );   /* XXX - release any other internal resources */
}


/* Example iterator hook routines - using 'get_next' to do most of the work */
netsnmp_variable_list *
ccAuditLoggingCfgTable_get_first_data_point(void **my_loop_context,
                          void **my_data_context,
                          netsnmp_variable_list *put_index_data,
                          netsnmp_iterator_info *mydata)
{
    *my_loop_context = ccAuditLoggingCfgTable_head;
	  //snmp_log( LOG_ERR,"GET_FIRST -> Fun:%s Line:%d \n", __func__, __LINE__);
    return ccAuditLoggingCfgTable_get_next_data_point(my_loop_context, my_data_context,
                                    put_index_data,  mydata );
}

netsnmp_variable_list *
ccAuditLoggingCfgTable_get_next_data_point(void **my_loop_context,
                          void **my_data_context,
                          netsnmp_variable_list *put_index_data,
                          netsnmp_iterator_info *mydata)
{
    struct ccAuditLoggingCfgTable_entry *entry = (struct ccAuditLoggingCfgTable_entry *)*my_loop_context;
    netsnmp_variable_list *idx = put_index_data;
    //static int cnt = 1;
    if ( entry ) {
        snmp_set_var_value( idx, entry->ccAuditLogsnmpv3UserName, sizeof(entry->ccAuditLogsnmpv3UserName) );
	 snmp_log( LOG_ERR,"In Func:get_next_data_point UserName:%s \n", entry->ccAuditLogsnmpv3UserName);
        idx = idx->next_variable;
        snmp_set_var_typed_integer( idx, ASN_IPADDRESS, entry->ccAuditLogsnmpClientIpAddr );
        idx = idx->next_variable;
        *my_data_context = (void *)entry;
        *my_loop_context = (void *)entry->next;
        return put_index_data;
    } else {
    	//snmp_log( LOG_ERR,"NULL Get_next-> Fun:%s Line:%d \n", __func__, __LINE__);
        return NULL;
    }
}


/** handles requests for the ccAuditLoggingCfgTable table */
int
ccAuditLoggingCfgTable_handler(
    netsnmp_mib_handler               *handler,
    netsnmp_handler_registration      *reginfo,
    netsnmp_agent_request_info        *reqinfo,
    netsnmp_request_info              *requests) {

    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    struct ccAuditLoggingCfgTable_entry          *table_entry;
    struct ccAuditLoggingCfgTable_entry          *table_row = NULL;
    int ret = SNMPERR_SUCCESS;

    DEBUGMSGTL(("ccAuditLoggingCfgTable:handler", "Processing request (%d)\n", reqinfo->mode));

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    	
    	  //snmp_log( LOG_ERR,"MODE_GET-> Fun:%s Line:%d \n", __func__, __LINE__);
            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGSNMPV3USERNAME:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
	 	snmp_log( LOG_ERR,"MODE_GET -> UserName:%s **\n", table_entry->ccAuditLogsnmpv3UserName);
                snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
                                 (u_char*)table_entry->ccAuditLogsnmpv3UserName,
                                          table_entry->ccAuditLogsnmpv3UserName_len);
                break;
            case COLUMN_CCAUDITLOGSNMPCLIENTIPADDR:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_IPADDRESS,
                                            table_entry->ccAuditLogsnmpClientIpAddr);
                break;
            case COLUMN_CCAUDITLOGROWSTATUS:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
               snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->ccAuditLogRowStatus);
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;
#if 0
        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
	    snmp_log( LOG_ERR,"RESERVE1 1 -> Fun:%s Line:%d \n", __func__, __LINE__);
        for (request=requests; request; request=request->next) {


		table_entry = (struct ccAuditLoggingCfgTable_entry *)
			netsnmp_extract_iterator_context(request);
		table_info  =     netsnmp_extract_table_info(      request);
		
/*
		var = request->requestvb;
		 memcpy( table[idx].name, var->val.string, var->val_len );
		           wlan_table[idx].name[var->val_len] = '\0';
		
		table_entry->ccAuditLogsnmpClientIpAddr     = *request->requestvb->val.integer;
		memcpy( table_entry->ccAuditLogsnmpv3UserName,
		                         request->requestvb->val.string,
					                         request->requestvb->val_len);
                 table_entry->ccAuditLogsnmpv3UserName_len =
			                         request->requestvb->val_len;
*/

	    if(NULL == table_entry){
		    table_entry = ccAuditLoggingCfgTable_createEntry("symbol", 7, 1111); 
		    table_entry->ccAuditLogRowStatus = RS_CREATEANDGO;
		    table_entry->valid = 1;
		    snmp_log( LOG_ERR,"\n :table_entry was NULL  \n");
	    }
	    //if(NULL == table_entry || NULL == table_info){
	    if(NULL == table_info){
	    	snmp_log( LOG_ERR,"\n MODE_SET_RESERVE1 :Table Details are Empty-> Fun:%s Line:%d \n", __func__, __LINE__);
		return -1;
	    }
	    snmp_log( LOG_ERR,"RESERVE1 2 return -> Fun:%s Line:%d \n", __func__, __LINE__);

            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGSNMPV3USERNAME:
	        /* or possibly 'netsnmp_check_vb_type_and_size' */
                ret = netsnmp_check_vb_type_and_size(
                          request->requestvb, ASN_OCTET_STR, sizeof(table_entry->ccAuditLogsnmpv3UserName));
                if ( ret != SNMP_ERR_NOERROR ) {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;
	    case COLUMN_CCAUDITLOGSNMPCLIENTIPADDR:
		/* or possibly 'netsnmp_check_vb_int_range' */
		ret = netsnmp_check_vb_type_and_size(
				request->requestvb, ASN_INTEGER, sizeof(long));
		/* ret = netsnmp_check_vb_int( request->requestvb ); */
		if ( ret != SNMP_ERR_NOERROR ) {
			netsnmp_set_request_error( reqinfo, request, ret );
			return SNMP_ERR_NOERROR;
		}
		break;
            case COLUMN_CCAUDITLOGROWSTATUS:
                ret = netsnmp_check_vb_rowstatus(request->requestvb,
                         (RS_NONEXISTENT ));
                         //(table_entry ? RS_ACTIVE : RS_NONEXISTENT ));
                if ( ret != SNMP_ERR_NOERROR ) {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;
            default:
                netsnmp_set_request_error( reqinfo, request,
                                           SNMP_ERR_NOTWRITABLE );
                return SNMP_ERR_NOERROR;
            }
        }
        break;

#endif
    case MODE_SET_RESERVE2:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);

#if 0
	    if(NULL == table_entry || NULL == table_info){
	    	snmp_log( LOG_ERR,"\n MODE_SET_RESERVE2 :Table Details are Empty-> Fun:%s Line:%d \n", __func__, __LINE__);
		return -1;
	    }
#endif
	    snmp_log( LOG_ERR,"RESERVE2  -> Fun:%s Line:%d \n", __func__, __LINE__);
    
            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    table_row = ccAuditLoggingCfgTable_createEntry(
                        table_info->indexes->val.string,
                        table_info->indexes->val_len,
                        *table_info->indexes->val.integer
                        );
                    if (table_row) {
                        netsnmp_insert_iterator_context(request, table_row);
                    } else {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_RESOURCEUNAVAILABLE );
                        return SNMP_ERR_NOERROR;
                    }
                }
            }
        }
        break;
    case MODE_SET_FREE:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
	    
	    if(NULL == table_entry || NULL == table_info){
	    	snmp_log( LOG_ERR," MODE_SET_FREE :Table Details are Empty-> Fun:%s Line:%d \n", __func__, __LINE__);
		return -1;
	    }
	    snmp_log( LOG_ERR,"SET_FREE -> Fun:%s Line:%d \n", __func__, __LINE__);
    
            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
			if (table_entry && !table_entry->valid) {
				if(NULL != table_row){
	    				snmp_log( LOG_ERR,"SET_FREE -> table_row in not NULL \n");
					ccAuditLoggingCfgTable_removeEntry(table_row );
				}
	    		snmp_log( LOG_ERR,"SET_FREE 222-> Fun:%s Line:%d \n", __func__, __LINE__);
			}
                }
            }
        }
        break;

    case MODE_SET_ACTION:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
	    
	    if(NULL == table_entry || NULL == table_info){
	    	snmp_log( LOG_ERR," MODE_SET_ACTION :Table Details are Empty-> Fun:%s Line:%d \n", __func__, __LINE__);
		return -1;
	    }
	    
	    snmp_log( LOG_ERR,"SET_ACTION -> Fun:%s Line:%d \n", __func__, __LINE__);
    
            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGSNMPV3USERNAME:
                memcpy( table_entry->old_ccAuditLogsnmpv3UserName,
                        table_entry->ccAuditLogsnmpv3UserName,
                        sizeof(table_entry->ccAuditLogsnmpv3UserName));
                table_entry->old_ccAuditLogsnmpv3UserName_len =
                        table_entry->ccAuditLogsnmpv3UserName_len;
                memset( table_entry->ccAuditLogsnmpv3UserName, 0,
                        sizeof(table_entry->ccAuditLogsnmpv3UserName));
                memcpy( table_entry->ccAuditLogsnmpv3UserName,
                        request->requestvb->val.string,
                        request->requestvb->val_len);
                table_entry->ccAuditLogsnmpv3UserName_len =
                        request->requestvb->val_len;
                break;
            case COLUMN_CCAUDITLOGSNMPCLIENTIPADDR:
                table_entry->old_ccAuditLogsnmpClientIpAddr = table_entry->ccAuditLogsnmpClientIpAddr;
                table_entry->ccAuditLogsnmpClientIpAddr     = *request->requestvb->val.integer;
                break;
            }
        }
        /* Check the internal consistency of an active row */
#if 0
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                /*   if (??) {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_INCONSISTENTVALUE );
                        return SNMP_ERR_NOERROR;
                    }*/
                }
            }
        }
#endif
        break;

    case MODE_SET_UNDO:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
   
	    if(NULL == table_entry || NULL == table_info){
	    	snmp_log( LOG_ERR,"MODE_SET_UNDO Table Details are Empty-> Fun:%s Line:%d \n", __func__, __LINE__);
		return -1;
	    }
	    snmp_log( LOG_ERR,"SET_UNDO -> Fun:%s Line:%d \n", __func__, __LINE__);

            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGSNMPV3USERNAME:
                memcpy( table_entry->ccAuditLogsnmpv3UserName,
                        table_entry->old_ccAuditLogsnmpv3UserName,
                        sizeof(table_entry->ccAuditLogsnmpv3UserName));
                memset( table_entry->old_ccAuditLogsnmpv3UserName, 0,
                        sizeof(table_entry->ccAuditLogsnmpv3UserName));
                table_entry->ccAuditLogsnmpv3UserName_len =
                        table_entry->old_ccAuditLogsnmpv3UserName_len;
                break;
            case COLUMN_CCAUDITLOGSNMPCLIENTIPADDR:
                table_entry->ccAuditLogsnmpClientIpAddr     = table_entry->old_ccAuditLogsnmpClientIpAddr;
                table_entry->old_ccAuditLogsnmpClientIpAddr = 0;
                break;
            case COLUMN_CCAUDITLOGROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    if (table_entry && !table_entry->valid) {
                        ccAuditLoggingCfgTable_removeEntry(table_row );
                    }
                }
                break;
            }
        }
        break;

    case MODE_SET_COMMIT:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ccAuditLoggingCfgTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
	    
	    if(NULL == table_entry || NULL == table_info){
	    	snmp_log( LOG_ERR," MODE_SET_COMMIT :Table Details are Empty-> Fun:%s Line:%d \n", __func__, __LINE__);
		return -1;
	    }
	    snmp_log( LOG_ERR,"COMMIT -> UserName:%s \n", table_entry->ccAuditLogsnmpv3UserName);

            switch (table_info->colnum) {
            case COLUMN_CCAUDITLOGROWSTATUS:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                    table_entry->valid = 1;
                    /* Fall-through */
                case RS_ACTIVE:
                    table_entry->ccAuditLogRowStatus = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    table_entry->valid = 1;
                    /* Fall-through */
                case RS_NOTINSERVICE:
                    table_entry->ccAuditLogRowStatus = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    ccAuditLoggingCfgTable_removeEntry(table_row );
                }
            }
        }
        break;
    }
    return SNMP_ERR_NOERROR;
}
