/*
 * Note: this file originally auto-generated by mib2c using
 * mib2c -c mib2c.container.conf
 */

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

static void     _cache_free(netsnmp_cache * cache, void *magic);
static int      _cache_load(netsnmp_cache * cache, void *vmagic);

/*
 * content of the sctpAssocTable 
 */
static netsnmp_container *sctpAssocTable_container;
static netsnmp_table_registration_info *table_info;

/** Initializes the sctpAssocTable module */
void
init_sctpAssocTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_sctpAssocTable();
}

void
shutdown_sctpAssocTable(void)
{
    shutdown_table_sctpAssocTable();
}

/** Initialize the sctpAssocTable table by defining its contents and how it's structured */
void
initialize_table_sctpAssocTable(void)
{
    static oid      sctpAssocTable_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 3 };
    size_t          sctpAssocTable_oid_len =
        OID_LENGTH(sctpAssocTable_oid);
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_cache  *cache = NULL;

    reg =
        netsnmp_create_handler_registration("sctpAssocTable",
                                            sctpAssocTable_handler,
                                            sctpAssocTable_oid,
                                            sctpAssocTable_oid_len,
                                            HANDLER_CAN_RWRITE);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpAssocTable\n");
        goto bail;
    }
    /** should a set on a non-existent row create a new one? */
    /** reg->modes |= HANDLER_CAN_NOT_CREATE; */

    container = netsnmp_container_find("sctpAssocTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR, "error creating container for sctpAssocTable\n");
        goto bail;
    }
    sctpAssocTable_container = container;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpAssocTable\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED,  /* index: sctpAssocId */
                                     0);
    table_info->min_column = COLUMN_SCTPASSOCREMHOSTNAME;
    table_info->max_column = COLUMN_SCTPASSOCDISCONTINUITYTIME;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpAssocTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpAssocTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(SCTP_TABLES_CACHE_TIMEOUT,     /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 sctpAssocTable_oid,
                                 sctpAssocTable_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR, "error creating cache for sctpAssocTable\n");
        goto bail;
    }
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET
        | NETSNMP_CACHE_AUTO_RELOAD | NETSNMP_CACHE_PRELOAD;
    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error creating cache handler for sctpAssocTable\n");
        goto bail;
    }

    netsnmp_cache_handler_owns_cache(handler);

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting cache handler for sctpAssocTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it */

    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,
                 "error registering table handler for sctpAssocTable\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    /*
     * Initialise the contents of the table here
     */


    return;                     /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail:                        /* not ok */

    if (handler)
        netsnmp_handler_free(handler);

    if (cache)
        netsnmp_cache_free(cache);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg)
        netsnmp_handler_registration_free(reg);
}

void
shutdown_table_sctpAssocTable(void)
{
    if (table_info) {
	netsnmp_table_registration_info_free(table_info);
	table_info = NULL;
    }
    if (sctpAssocTable_container)
	sctpAssocTable_container_clear(sctpAssocTable_container);
}


/** handles requests for the sctpAssocTable table */
int
sctpAssocTable_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;
    sctpAssocTable_entry *table_entry;

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;
            table_entry = (sctpAssocTable_entry *)
                netsnmp_container_table_extract_context(request);
            table_info = netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for sctpAssocTable\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_SCTPASSOCREMHOSTNAME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *)
                                         table_entry->sctpAssocRemHostName,
                                         table_entry->sctpAssocRemHostName_len);
                break;
            case COLUMN_SCTPASSOCLOCALPORT:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocLocalPort);
                break;
            case COLUMN_SCTPASSOCREMPORT:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocRemPort);
                break;
            case COLUMN_SCTPASSOCREMPRIMADDRTYPE:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->sctpAssocRemPrimAddrType);
                break;
            case COLUMN_SCTPASSOCREMPRIMADDR:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *)
                                         table_entry->sctpAssocRemPrimAddr,
                                         table_entry->sctpAssocRemPrimAddr_len);
                break;
            case COLUMN_SCTPASSOCHEARTBEATINTERVAL:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocHeartBeatInterval);
                break;
            case COLUMN_SCTPASSOCSTATE:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->sctpAssocState);
                break;
            case COLUMN_SCTPASSOCINSTREAMS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocInStreams);
                break;
            case COLUMN_SCTPASSOCOUTSTREAMS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocOutStreams);
                break;
            case COLUMN_SCTPASSOCMAXRETR:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocMaxRetr);
                break;
            case COLUMN_SCTPASSOCPRIMPROCESS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocPrimProcess);
                break;
            case COLUMN_SCTPASSOCT1EXPIREDS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           table_entry->sctpAssocT1expireds);
                break;
            case COLUMN_SCTPASSOCT2EXPIREDS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           table_entry->sctpAssocT2expireds);
                break;
            case COLUMN_SCTPASSOCRTXCHUNKS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           table_entry->sctpAssocRtxChunks);
                break;
            case COLUMN_SCTPASSOCSTARTTIME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_TIMETICKS,
                                           table_entry->sctpAssocStartTime);
                break;
            case COLUMN_SCTPASSOCDISCONTINUITYTIME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_TIMETICKS,
                                           table_entry->sctpAssocDiscontinuityTime);
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;
            netsnmp_set_request_error(reqinfo, request,
                                      SNMP_ERR_NOTWRITABLE);
        }
        break;

    case MODE_SET_RESERVE2:
    case MODE_SET_FREE:
    case MODE_SET_ACTION:
    case MODE_SET_UNDO:
    case MODE_SET_COMMIT:
        break;
    }
    return SNMP_ERR_NOERROR;
}

/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    DEBUGMSGTL(("internal:sctpAssocTable:_cache_load", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache for sctpAssocTable_cache_load\n");
        return -1;
    }
    /** should only be called for an invalid or expired cache */
    netsnmp_assert((0 == cache->valid) || (1 == cache->expired));

    return sctpTables_load();
}                               /* _cache_load */

/**
 * @Internal
 */
/** remove a row from the table */
static void
sctpAssocTable_freeEntry_cb(sctpAssocTable_entry * entry, void *magic)
{

    sctpAssocTable_entry_free(entry);
}

/**
 * @internal
 */
static void
_cache_free(netsnmp_cache * cache, void *magic)
{
    netsnmp_container *container;

    DEBUGMSGTL(("internal:sctpAssocTable:_cache_free", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache in sctpAssocTable_cache_free\n");
        return;
    }
    container = (netsnmp_container *) cache->magic;

    /*
     * empty (but don't free) cache here
     */
    CONTAINER_CLEAR(container, (netsnmp_container_obj_func *)
                    sctpAssocTable_freeEntry_cb, NULL);
}                               /* _cache_free */

sctpAssocTable_entry *
sctpAssocTable_entry_create(void)
{
    sctpAssocTable_entry *entry =
        SNMP_MALLOC_TYPEDEF(sctpAssocTable_entry);
    if (entry != NULL) {
        entry->oid_index.len = SCTP_ASSOC_TABLE_INDEX_SIZE;
        entry->oid_index.oids = entry->oid_tmp;
    }

    return entry;
}

int
sctpAssocTable_entry_update_index(sctpAssocTable_entry * entry)
{
    netsnmp_variable_list var_sctpAssocId;
    int             err = 0;

    /*
     * prepare the value to be converted 
     */
    memset(&var_sctpAssocId, 0, sizeof(var_sctpAssocId));
    var_sctpAssocId.type = ASN_UNSIGNED;
    var_sctpAssocId.next_variable = NULL;
    snmp_set_var_value(&var_sctpAssocId, (u_char *) & entry->sctpAssocId,
                       sizeof(entry->sctpAssocId));

    /*
     * convert it 
     */
    err =
        build_oid_noalloc(entry->oid_index.oids, entry->oid_index.len,
                          &entry->oid_index.len, NULL, 0,
                          &var_sctpAssocId);
    if (err)
        snmp_log(LOG_ERR, "error %d converting index to oid\n", err);

    /*
     * release any memory allocated during the conversion 
     */
    snmp_reset_var_buffers(&var_sctpAssocId);

    return err;
}

void
sctpAssocTable_entry_copy(sctpAssocTable_entry * from,
                          sctpAssocTable_entry * to)
{
    memcpy(to, from, sizeof(sctpAssocTable_entry));
    to->oid_index.oids = to->oid_tmp;
}


void
sctpAssocTable_entry_free(sctpAssocTable_entry * entry)
{
    SNMP_FREE(entry);
}

netsnmp_container *
sctpAssocTable_get_container(void)
{
    return sctpAssocTable_container;
}

static void
sctpAssocTable_entry_clear(void *what, void *magic)
{
    sctpAssocTable_entry_free(what);
}

void
sctpAssocTable_container_clear(netsnmp_container *container)
{
    CONTAINER_CLEAR(container, sctpAssocTable_entry_clear, NULL);
}
