/*
 * Copyright Notice:
 * Copyright Treck Incorporated  1997 - 2004.
 * Copyright Elmic Incorporated  1997 - 2004.
 * No portions or the complete contents of this file may be copied or
 * distributed in any form (including but not limited to printed or electronic
 * forms) without the expressed written consent of Treck Inc OR Elmic Systems.
 * Copyright laws and International Treaties protect the contents of this
 * file. Unauthorized use is prohibited. All rights reserved.
 *
 * Description:
 *
 * Filename: example_var.c
 * Generated by The Treck MIB compiler - version 1.23.
 * Date Created: Tue Dec 05 14:32:22 2006
 */


#include "trdefs.h"
#include "trasn1.h"
#include "trsnmp.h"
#include "trimpl.h"
#include "trmib.h"
#include "trconsts.h"
#ifdef TM_SNMP_AGENT_V3
#include "trsnmpv3.h"
#include "trdeskey.h"
#endif /* TM_SNMP_AGENT_V3 */
#include "trregstr.h"
#include "example_var.h"
#include "example_local.h"

#define TM_SNMP_VERSION  1
#define return_buf ((ttSnmpdPtr)tm_context(tvSnmpdPtr))->snmpGlobalReturnU.snmpBufReturn
#define long_return ((ttSnmpdPtr)tm_context(tvSnmpdPtr))->snmpGlobalReturnU.snmpLongReturn
#define longlong_return ((ttSnmpdPtr)tm_context(tvSnmpdPtr))->snmpGlobalReturnU.snmpLongLongReturn


#define IP2LONG(name,x)    (ntohl(((name)[(x)]&0x000000ff)<<24))| \
                 (ntohl(((name)[(x)+1]&0x000000ff)<<16))| \
                 (ntohl(((name)[(x)+2]&0x000000ff)<<8))| \
                 ntohl(((name)[(x)+3]&0x000000ff))

extern int tfProcessObjid(u_char *, int *, u_char *, oid *, int *);
extern int tfProcessString(u_char *, int *, u_char *, u_char *, int, int *, int);
extern int tfProcessInt(u_char *, int *, u_char *, long *);
extern int tfProcessUnsignedInt(u_char *, int *, u_char *, long *);
extern int tfProcessIpAddr(u_char *, int *, u_char *, long *);
extern int tfCompare(oid *, int, oid *, int);
extern struct tsSnmpTrapVarBind *tfFillTrapVars(oid *, int , int, void *, int, int *);
extern void tfFreeBindings(struct tsSnmpTrapVarBind *);
extern long tfGetMibUptime(void);
#if (TM_SNMP_VERSION == 3)
extern int tfSendNotifications(char *, struct tsSnmpTrapVarBind *, oid, tt32Bit, int, int);
#else /* (TM_SNMP_VERSION == 3) */
extern int tfSendTrapsV1(int , int , struct tsSnmpTrapVarBind * );
#if (TM_SNMP_VERSION == 2)
extern int tfSendTrapsV2(struct tsSnmpTrapVarBind *);
#endif /* (TM_SNMP_VERSION == 2) */
#endif /* (TM_SNMP_VERSION == 3) */

int greenledon_values[2] = {1, 2};
int yellowledon_values[2] = {1, 2};
int rowstatus_values[6] = {1, 2, 3, 4, 5, 6};

/***    OIDs used in all trap messages    ***/

static oid sysuptime_oid[] = {1,3,6,1,2,1,1,3,0};
static oid snmptrapiod_iod[] = {1,3,6,1,6,3,1,1,4,1,0};

/***    Other thap OIDs  ***/

static oid exampletrapgreen_iod[] = {1,3,6,1,4,1,901,999,1,3,1,0};
static oid exampletrapyellow_iod[] = {1,3,6,1,4,1,901,999,1,3,2,0};


/***    Groups retrieval functions    ***/

u_char *tfvar_group(
        struct tsSnmpVariable *vp, oid *name, 
        int *length, int exact, int *var_len, 
        int (**write_method)(int action, u_char *var_val, 
        u_char var_val_type, int var_val_len, oid *name, int length), 
        int (**create_method)(oid *index, int index_length, oid status),
        int (**delete_method)(oid *index, int index_length))
{
    oid  *current = NULL;
//    int   i = 0;
    int   vlength;
    char *hold_ptr = NULL;
    long *long_ptr = NULL;
    void *returnValue = NULL;
    int   result;

    *create_method = tm_snmp_create_null_method;
    *delete_method = tm_snmp_delete_null_method;

    current = (oid *)tm_snmp_malloc(TM_SNMP_MAX_NAME_LEN*sizeof(oid));
    if (current == NULL)
    {
        returnValue = NULL;
        goto exitFunction;
    }
    tm_snmp_memcpy((char *)current, (char *)vp->svarName, 
                   (int)vp->svarNameLen * sizeof(oid));
    current[vp->svarNameLen] = 0;
    result = tfCompare(name, *length, current, (int)vp->svarNameLen + 1);
    if((exact && (result != 0)) || (!exact && (result >= 0)))
    {
        returnValue = NULL;
        goto exitFunction;
    }
    tm_snmp_memcpy((char *)name, (char *)current, 
    ((int)vp->svarNameLen + 1) * sizeof(oid));
    *length = vp->svarNameLen + 1;

    switch(vp->svarMagic)
    {
    case GREENLEDON:
            *write_method  = tfset_group;
        long_ptr = tfgroup_get(vp->svarMagic, &vlength);
        if (!long_ptr)
        {
            returnValue = NULL;
            goto exitFunction;
        }
        long_return = *long_ptr;
        *var_len = sizeof(long);
        returnValue = (void *)(&long_return);
        goto exitFunction;
    case YELLOWLEDON:
            *write_method  = tfset_group;
        long_ptr = tfgroup_get(vp->svarMagic, &vlength);
        if (!long_ptr)
        {
            returnValue = NULL;
            goto exitFunction;
        }
        long_return = *long_ptr;
        *var_len = sizeof(long);
        returnValue = (void *)(&long_return);
        goto exitFunction;
    case BIGBOSS:
            *write_method  = tfset_group;
        hold_ptr = (char *)tfgroup_get(vp->svarMagic, &vlength);
        if(!hold_ptr)
        {
            returnValue = NULL;
            goto exitFunction;
        }
        tm_snmp_memcpy((char *)return_buf, (char *)hold_ptr, (int)vlength);
        *var_len = vlength;
        returnValue = (void *)return_buf;
        goto exitFunction;
    default:
        returnValue = NULL;
        goto exitFunction;
    }
exitFunction:
    if (current != NULL)
    {
        tm_snmp_free(current);
    }
    return (u_char *)returnValue;
}


/***    Groups setting functions        ***/

int tfset_group(
        int action, u_char *var_val, u_char var_val_type, 
        int var_val_len, oid *name, int length)
{
    long    intp;
    int     k = 0;
    u_char *buf;
    int     size;
    int     string_type;
    int     err;

    size = MAX_STRING_LEN;
    buf = (u_char *)tm_snmp_malloc(MAX_STRING_LEN);
    if (buf == NULL)
    {
        err = TM_SNMP_ERR_RESOURCEUNAVAILABLE;
        goto exitFunction;
    }
    if (var_val_type == TM_SNMP_INTEGER)
    {
        switch(name[10])
        {
        case 1:
        case 2:
            if ((err = tfProcessInt(var_val, &var_val_len, &var_val_type, &intp))
                   != TM_SNMP_ERR_NOERROR)
            {
                goto exitFunction;
            }
            break;
        default:
            err = TM_SNMP_ERR_WRONGTYPE;
            goto exitFunction;
        }
    }
    else    if (var_val_type == TM_SNMP_STRING)
    {
        switch(name[10])
        {
        case 3:
            string_type = TM_SNMP_STRING;
            break;
        default:
            err = TM_SNMP_ERR_WRONGTYPE;
            goto exitFunction;
        }
        if ((err=tfProcessString(
                var_val, &var_val_len, &var_val_type, buf,
                MAX_STRING_LEN, &size, string_type)) != TM_SNMP_ERR_NOERROR)
        {
            goto exitFunction;
        }
    }
    else
    {
        err = TM_SNMP_ERR_WRONGTYPE;
        goto exitFunction;
    }
    if (var_val_type == TM_SNMP_INTEGER)
    {
        switch(name[9])
        {
        case 1:
            for (k=0; k<2; k++)
            {
                if (intp == greenledon_values[k])
                    break;
            }
            if (k==2)
            {
                err = TM_SNMP_ERR_WRONGVALUE;
                goto exitFunction;
            }
            break;
        case 2:
            for (k=0; k<2; k++)
            {
                if (intp == yellowledon_values[k])
                    break;
            }
            if (k==2)
            {
                err = TM_SNMP_ERR_WRONGVALUE;
                goto exitFunction;
            }
            break;
        default:
            break;
        }
    }
    if (var_val_type == TM_SNMP_STRING)
    {
        switch(name[10])
        {
        case 3:
            if (size < BIGBOSS_LOWER_LIMIT ||
                size > BIGBOSS_UPPER_LIMIT)
            {
                err = TM_SNMP_ERR_WRONGVALUE;
                goto exitFunction;
            }
            break;
        default:
            break;
        }
    }
    if (action !=TM_SNMP_COMMIT)
    {
        err = TM_SNMP_ERR_NOERROR;
        goto exitFunction;
    }

    switch(name[10])
    {
    case 1:
        if (tfwrite_group(GREENLEDON, (u_char *)&intp, sizeof(long)) == OK)
        {
            err = TM_SNMP_ERR_NOERROR;
            goto exitFunction;
        }
        else
        {
            err = TM_SNMP_ERR_GENERR;
            goto exitFunction;
        }
    case 2:
        if (tfwrite_group(YELLOWLEDON, (u_char *)&intp, sizeof(long)) == OK)
        {
            err = TM_SNMP_ERR_NOERROR;
            goto exitFunction;
        }
        else
        {
            err = TM_SNMP_ERR_GENERR;
            goto exitFunction;
        }
    case 3:
        if (tfwrite_group(BIGBOSS, buf, size) == OK)
        {
            err = TM_SNMP_ERR_NOERROR;
            goto exitFunction;
        }
        else
        {
            err = TM_SNMP_ERR_GENERR;
            goto exitFunction;
        }
    default:
        break;
    }
    err = TM_SNMP_ERR_NOSUCHNAME;
exitFunction:
    if (buf != NULL)
    {
        tm_snmp_free(buf);
    }
        return err;
}


extern int exampleEntryCreate(oid *index, int index_length, oid status);
extern int exampleEntryDelete(oid *index, int index_length);

/***    Tables retrieval functions    ***/

u_char *tfvar_simpletable(        struct tsSnmpVariable *vp, oid *name, 
        int *length, int exact, int *var_len, 
        int (**write_method)(int action, u_char *var_val, 
        u_char var_val_type, int var_val_len, oid *name, int length), 
        int (**create_method)(oid *index, int index_length, oid status),
        int (**delete_method)(oid *index, int index_length))
{
    oid  *current = NULL;
    int   i;
    char *hold_ptr = NULL;
    void *returnValue = NULL;
    //int   k = 0;
    struct simpletable_entry *entry0;
    int position;

    position = 13;
    *create_method = exampleEntryCreate;
    *delete_method = exampleEntryDelete;
    current = (oid *)tm_snmp_malloc(TM_SNMP_MAX_NAME_LEN*sizeof(oid));
    if (current == NULL)
    {
        returnValue = NULL;
        goto exitFunction;
    }
    tm_snmp_memset((char *)current, 0, TM_SNMP_MAX_NAME_LEN*sizeof(oid));
    tm_snmp_memcpy((char *)current, (char *)vp->svarName, (int)vp->svarNameLen * sizeof(oid));

    entry0 = (struct simpletable_entry *)
            tm_snmp_malloc(sizeof(struct simpletable_entry));
    if (entry0 == NULL)
    {
        goto exitFunction;
    }
    tm_snmp_memset(entry0, 0, sizeof(struct simpletable_entry));
    entry0->index = (exact ? name[13] : (unsigned)-1);
    for (;;)
    {
        position = 13;
        if (!tfsimpletable_entry_get(exact, entry0))
        {
            break;
        }
            if((position + 2) > TM_SNMP_MAX_NAME_LEN)
/* Oid for string index exceeds maximum oid name length */
            {
                goto exitFunction;
            }
        current[13] = (oid)entry0->index;
        /* compare OIDs : */
        if((exact && tfCompare(current, 14, name, *length) == 0 ) ||
           (!exact && tfCompare(current, 14, name, *length) > 0 ))
        {
            *length = 14;
            for (i = 0; i < 14; i++)
            {
                name[i] = current[i];
            }
            switch(vp->svarMagic)
            {
            case INDEX:
                *write_method = NULL;
                long_return = entry0->index;
                *var_len = sizeof(long);
                returnValue = (void *)(&long_return);
                goto exitFunction;
            case ROWSTATUS:
                *write_method  = tfset_simpletable_entry;
                long_return = entry0->rowstatus;
                *var_len = sizeof(long);
                returnValue = (void *)(&long_return);
                goto exitFunction;
            case NAME:
                *write_method  = tfset_simpletable_entry;
                hold_ptr = (char *)entry0->name;
                if (!hold_ptr)
                {
                    returnValue = NULL;
                    goto exitFunction;
                }
                tm_snmp_memcpy((char *)return_buf, (char *)hold_ptr, 
                                entry0->name_len);
                *var_len = entry0->name_len;
                    returnValue = (void *)return_buf;
                goto exitFunction;
            default:
                returnValue = NULL;
                goto exitFunction;
            }
        }
        if(exact)
        {
            returnValue = NULL;
            goto exitFunction;
        }
    }

    returnValue = NULL;

exitFunction:
    if (current != NULL)
    {
        tm_snmp_free(current);
    }
    if (entry0 != NULL)
    {
        tm_snmp_free(entry0);
    }
    return (u_char *)returnValue;
}

int tfset_simpletable_entry(
        int action, u_char *var_val, u_char var_val_type, 
        int var_val_len, oid *name, int length)
{
    long    intp = 0;
    u_char *buf = NULL;
    int     size = 0;
    int     string_type = 0;
    int     err;
    int     position = 0;
    int     k = 0;
    int     index0;

    size = MAX_STRING_LEN;
    buf = (u_char *)tm_snmp_malloc(MAX_STRING_LEN);
    if (buf == NULL)
    {
        err = TM_SNMP_ERR_RESOURCEUNAVAILABLE;
        goto exitFunction;
    }

    position = 13;
    index0 = (int)name[position/*13*/];
	if (var_val_type == TM_SNMP_INTEGER)
    {
        switch(name[12])
        {
        case 2:
            if ((err = tfProcessInt(var_val, &var_val_len, &var_val_type, &intp))
                   != TM_SNMP_ERR_NOERROR)
            {
                goto exitFunction;
            }
            break;
        default:
            err = TM_SNMP_ERR_WRONGTYPE;
            goto exitFunction;
        }
    }
	else if (var_val_type == TM_SNMP_STRING)
    {
        switch(name[12])
        {
        case 3:
            string_type = TM_SNMP_STRING;
            break;
        default:
            err = TM_SNMP_ERR_WRONGTYPE;
            goto exitFunction;
        }
        if ((err=tfProcessString(
                var_val, &var_val_len, &var_val_type, buf,
                MAX_STRING_LEN, &size, string_type)) != TM_SNMP_ERR_NOERROR)
        {
            goto exitFunction;
        }
    }
    else
    {
        err = TM_SNMP_ERR_WRONGTYPE;
        goto exitFunction;
    }
    if ((var_val_type == TM_SNMP_INTEGER) ||
        (var_val_type == TM_SNMP_GAUGE))
    {
        switch(name[12])
        {
        case 2:
            for (k=0; k<6; k++)
            {
                if (intp == rowstatus_values[k])
                    break;
            }
            if (k==6)
            {
                err = TM_SNMP_ERR_WRONGVALUE;
                goto exitFunction;
            }
            break;
        default:
            break;
        }
    }
    if (var_val_type == TM_SNMP_STRING)
    {
        switch(name[12])
        {
        case 3:
            if (size < NAME_LOWER_LIMIT ||
                size > NAME_UPPER_LIMIT)
            {
                err = TM_SNMP_ERR_WRONGVALUE;
                goto exitFunction;
            }
            break;
        default:
            break;
        }
    }
    if (action !=TM_SNMP_COMMIT)
    {
        err = TM_SNMP_ERR_NOERROR;
        goto exitFunction;
    }

    switch(name[12])
    {
    case 2:
        if (tfwrite_simpletable_entry(
                index0, 
                ROWSTATUS,
                (u_char *)&intp, sizeof(long)) == OK)
        {
            err = TM_SNMP_ERR_NOERROR;
            goto exitFunction;
        }
        else
        {
            err = TM_SNMP_ERR_GENERR;
            goto exitFunction;
        }
    case 3:
        if (tfwrite_simpletable_entry(
                index0, 
                NAME,
                buf, size) == OK)
        {
            err = TM_SNMP_ERR_NOERROR;
            goto exitFunction;
        }
        else
        {
            err = TM_SNMP_ERR_GENERR;
            goto exitFunction;
        }
    default:
        break;
    }
    err = TM_SNMP_ERR_NOSUCHNAME;
exitFunction:
    if (buf != NULL)
    {
        tm_snmp_free(buf);
    }
    return err;
}

/**      TRAPS PART     **/

int tfexampletrapgreen_trap(struct exampletrapgreen *entry)
{
    struct tsSnmpTrapVarBind *pass, *start_pass, *start_pass1 = NULL;
    int oid_len;
    int pdu_error;
//    int send_len = 0;
    oid varbind_oid[TM_SNMP_MAX_NAME_LEN];
    int timev;
    int i, n;

    timev = tfGetMibUptime ();
    pass = start_pass = tfFillTrapVars (sysuptime_oid, 9, TM_SNMP_TIMETICKS,
                                        &timev, 1, &pdu_error);
    if(pdu_error)
    {
        tm_snmp_log_msg1("Error %d building pass\n", pdu_error);
        tfFreeBindings(start_pass);
        return -1;
    }

    pass->next = tfFillTrapVars (snmptrapiod_iod, 11, ASN_OBJECT_ID,
                                (char *)exampletrapgreen_iod, 11, &pdu_error);
    if(pdu_error)
    {
        tm_snmp_log_msg1("Error %d building pass\n", pdu_error);
        tfFreeBindings(start_pass);
        return -1;
    }
    pass = pass->next;

    for (i=0; i<1; i++)
    {
        int   type;
        void *p;
        int   v_len;
//        int   k = 0;
        int   position;
        switch(i)
        {
        case 0:
            varbind_oid[0] = 1;
            varbind_oid[1] = 3;
            varbind_oid[2] = 6;
            varbind_oid[3] = 1;
            varbind_oid[4] = 4;
            varbind_oid[5] = 1;
            varbind_oid[6] = 901;
            varbind_oid[7] = 999;
            varbind_oid[8] = 1;
            varbind_oid[9] = 1;
            varbind_oid[10] = 1;
            position = 11;
            varbind_oid[11] = entry->index0_0;
            position++;
            oid_len = position;
            p = &entry->greenledon;
            v_len = 1;
            type = TM_SNMP_INTEGER;
            break;
        default:
            break;
        }
        pass->next = tfFillTrapVars(varbind_oid, oid_len, type,
                                    (char *)p, v_len, &pdu_error);
        if(pdu_error)
        {
            tm_snmp_log_msg1("Error %d building pass\n", pdu_error);
            tfFreeBindings(start_pass);
            return -1;
        }
        pass = pass->next;
        if (i == 0)
        {
            start_pass1 = pass;
        }
    }

#if (TM_SNMP_VERSION == 3)
    {
    int enterprise_len;
    oid enterprise_num;
    enterprise_len = tfGetEnterpriseNumber(&enterprise_num);
    n = tfSendNotifications("defaultnotification", start_pass,
                            enterprise_num,
                            enterprise_len,
                            6, entry->trap_id);
    }
#else /* TM_SNMP_VERSION == 3 */
    n = tfSendTrapsV1(6, entry->trap_id, start_pass1);
#if (TM_SNMP_VERSION == 2)
    n = tfSendTrapsV2(start_pass);
#endif /* TM_SNMP_VERSION == 2 */
#endif /* TM_SNMP_VERSION == 3 */
    tfFreeBindings(start_pass);
    return n;
}
int tfexampletrapyellow_trap(struct exampletrapyellow *entry)
{
    struct tsSnmpTrapVarBind *pass, *start_pass, *start_pass1 = NULL;
    int oid_len;
    int pdu_error;
//    int send_len = 0;
    oid varbind_oid[TM_SNMP_MAX_NAME_LEN];
    int timev;
    int i, n;

    timev = tfGetMibUptime ();
    pass = start_pass = tfFillTrapVars (sysuptime_oid, 9, TM_SNMP_TIMETICKS,
                                        &timev, 1, &pdu_error);
    if(pdu_error)
    {
        tm_snmp_log_msg1("Error %d building pass\n", pdu_error);
        tfFreeBindings(start_pass);
        return -1;
    }

    pass->next = tfFillTrapVars (snmptrapiod_iod, 11, ASN_OBJECT_ID,
                                (char *)exampletrapyellow_iod, 11, &pdu_error);
    if(pdu_error)
    {
        tm_snmp_log_msg1("Error %d building pass\n", pdu_error);
        tfFreeBindings(start_pass);
        return -1;
    }
    pass = pass->next;

    for (i=0; i<1; i++)
    {
        int   type;
        void *p;
        int   v_len;
//        int   k = 0;
        int   position;
        switch(i)
        {
        case 0:
            varbind_oid[0] = 1;
            varbind_oid[1] = 3;
            varbind_oid[2] = 6;
            varbind_oid[3] = 1;
            varbind_oid[4] = 4;
            varbind_oid[5] = 1;
            varbind_oid[6] = 901;
            varbind_oid[7] = 999;
            varbind_oid[8] = 1;
            varbind_oid[9] = 1;
            varbind_oid[10] = 2;
            position = 11;
            varbind_oid[11] = entry->index0_0;
            position++;
            oid_len = position;
            p = &entry->yellowledon;
            v_len = 1;
            type = TM_SNMP_INTEGER;
            break;
        default:
            break;
        }
        pass->next = tfFillTrapVars(varbind_oid, oid_len, type,
                                    (char *)p, v_len, &pdu_error);
        if(pdu_error)
        {
            tm_snmp_log_msg1("Error %d building pass\n", pdu_error);
            tfFreeBindings(start_pass);
            return -1;
        }
        pass = pass->next;
        if (i == 0)
        {
            start_pass1 = pass;
        }
    }
#if (TM_SNMP_VERSION == 3)
    {
    int enterprise_len;
    oid enterprise_num;
    enterprise_len = tfGetEnterpriseNumber(&enterprise_num);
    n = tfSendNotifications("defaultnotification", start_pass,
                            enterprise_num,
                            enterprise_len,
                            6, entry->trap_id);
    }
#else /* TM_SNMP_VERSION == 3 */
    n = tfSendTrapsV1(6, entry->trap_id, start_pass1);
#if (TM_SNMP_VERSION == 2)
    n = tfSendTrapsV2(start_pass);
#endif /* TM_SNMP_VERSION == 2 */
#endif /* TM_SNMP_VERSION == 3 */
    tfFreeBindings(start_pass);
    return n;
}
