/*
 * This file implements the RTP-MIB module.
 * $Id: rtp-mib-sender.c 8676 2008-01-17 23:11:17Z ispringer $
 */
/* General includes */
#include <stdio.h>
#include <sys/types.h>

#ifdef WIN32
/* Apache includes */
#include <httpd.h>
#include <http_log.h>
#include <apr_hash.h>
#include <apr_optional.h>
#endif

/* SNMP includes */
#include <ucd-snmp-config.h>
#include <asn1.h>
#include <snmp.h>
#include <snmp_api.h>
#include <snmp_impl.h>
#include <snmp_debug.h>
#include <snmp_vars.h>
#include <var_struct.h>

#include "covalent-snmp-config.h"
#include "rtp-mib/rtp-mib.h"

#ifndef SNMP_MIN
#define SNMP_MIN(a,b)   (((a)<(b)) ? (a) : (b))
#endif

#define NEXT    FALSE
#define EXACT   TRUE
#define INDEX   2

/* Definitions for the columnar objects. */
/* rtpSenderInverseTable                 */
#define RTPSENDERINVERSESTARTTIME        1

/* rtpSenderTable                        */
#define RTPSENDERCNAME                   2
#define RTPSENDERADDR                    3
#define RTPSENDERPACKETS                 4
#define RTPSENDEROCTETS                  5
#define RTPSENDERTOOL                    6
#define RTPSENDERSRS                     7
#define RTPSENDERSRTIME                  8
#define RTPSENDERPT                      9
#define RTPSENDERSTARTTIME               10

#ifdef RTP_SENDER_GROUP
rtp_session_info_t *top_session;

rtp_session_info_t *
get_rtp_sender_inverse_entry_index(
        oid *name, size_t *namelength,
        oid *newname, size_t *newname_length,
        int exact, rtp_session_info_t *session)
{
size_t  len = *newname_length;
int i;
int result;

    while (session) {
        *newname_length = len;

        /* Compute the rtpSessionDomain index portion */
        newname[ len ] = session->rtpSessionDomainLength;
        for( i = 0 ; i < session->rtpSessionDomainLength ; i++ )
                newname[ *newname_length++ ] = session->rtpSessionDomain[ i ];

        /* Compute the rtpSenderAddr index portion */
        newname[ *newname_length++ ] = 6;
        newname[ *newname_length++ ] = session->rtpSenderAddr[0];
        newname[ *newname_length++ ] = session->rtpSenderAddr[1];
        newname[ *newname_length++ ] = session->rtpSenderAddr[2];
        newname[ *newname_length++ ] = session->rtpSenderAddr[3];
        newname[ *newname_length++ ] = (session->rtpSenderAddrPort / 256);
        newname[ *newname_length++ ] = (session->rtpSenderAddrPort % 256);

        /* Compute the rtpSessionIndex index portion */
        newname[ *newname_length++ ] = session->rtpSessionIndex;

        /* Compute the rtpSessionSSRC index portion */
        newname[ *newname_length++ ] = session->rtpSenderSSRC;

        result = snmp_oid_compare(name, *namelength, newname, *newname_length);
        if (((exact == NEXT) && (0 > result)) ||
            ((exact == EXACT) && (0 == result))) {
            return(session);
        }
        session = session->next_in_rtpSenderInverseTable;
    }
    return(NULL);
}

static unsigned char *
read_rtpSenderInverseEntry(struct variable *vp,
    oid *name, size_t *length,
    int exact, size_t *var_len, WriteMethod **write_method)
{
oid newname[ MAX_OID_LEN ];
size_t newname_length;
rtp_session_info_t *session;

    newname_length = vp->namelen;
    memcpy((char *)newname, (char *)vp->name, newname_length * sizeof(oid));
    session = get_rtp_sender_inverse_entry_index(
                                name, length, newname, &newname_length,
                                exact, top_session);
    if (session) {
        session = session->next_in_rtpSenderInverseTable;
    }

    *length = newname_length;
    memcpy( (char *)name,(char *)newname, *length * sizeof(oid));
    *write_method = 0;
    *var_len = sizeof(long);

    switch (vp->magic) {
    case RTPSENDERINVERSESTARTTIME:
        return (unsigned char *) NULL;
    default:
         ERROR_MSG("");
    }
    return NULL;
}

rtp_session_info_t *
get_rtp_sender_entry_index(int exact,
        oid *name, size_t *namelength,
        oid *newname, size_t *newname_length,
        rtp_session_info_t *session)
{
int result;
int len = *newname_length;

    while (session) {
        *newname_length = len;

        /* Compute the rtpSessionIndex index portion */
        newname[ *newname_length++ ] = session->rtpSessionIndex;

        /* Compute the rtpSessionSSRC index portion */
        newname[ *newname_length++ ] = session->rtpSenderSSRC;

        result = snmp_oid_compare(name, *namelength, newname, *newname_length);
        if (((exact == NEXT) && (0 > result)) ||
            ((exact == EXACT) && (0 == result))) {
            return(session);
        }
        session = session->next_in_rtpSenderTable;
    }
    return(NULL);
}


static unsigned char *
read_rtpSenderEntry(struct variable *vp,
    oid *name, size_t *length,
    int exact, size_t *var_len, WriteMethod **write_method)
{
oid newname[ MAX_OID_LEN ];
size_t newname_length;
rtp_session_info_t *session;

    newname_length = vp->namelen;
    memcpy((char *)newname, (char *)vp->name, newname_length * sizeof(oid));
    session = get_rtp_sender_entry_index(exact,
                                name, length, newname, &newname_length, top_session);
    if (session) {
        session = session->next_in_rtpSenderInverseTable;
    }

    *length = newname_length;
    memcpy( (char *)name,(char *)newname, *length * sizeof(oid));
    *write_method = 0;
    *var_len = sizeof(long);

    switch (vp->magic) {
    case RTPSENDERCNAME:
        return (unsigned char *) NULL;
    case RTPSENDERADDR:
        return (unsigned char *) NULL;
    case RTPSENDERPACKETS:
        return (unsigned char *) NULL;
    case RTPSENDEROCTETS:
        return (unsigned char *) NULL;
    case RTPSENDERTOOL:
        return (unsigned char *) NULL;
    case RTPSENDERSRS:
        return (unsigned char *) NULL;
    case RTPSENDERSRTIME:
        return (unsigned char *) NULL;
    case RTPSENDERPT:
        return (unsigned char *) NULL;
    case RTPSENDERSTARTTIME:
        return (unsigned char *) NULL;
    default:
         ERROR_MSG("");
    }
    return NULL;
}

static oid rtpSenderInverseEntry_oid[] = {1, 3, 6, 1, 2, 1, 87, 1, 4, 1};
struct variable2 rtpSenderInverseEntry_variables[] = {
    { RTPSENDERINVERSESTARTTIME, ASN_INTEGER, RONLY, read_rtpSenderInverseEntry, 1, {1} },
};

static oid rtpSenderEntry_oid[] = {1, 3, 6, 1, 2, 1, 87, 1, 5, 1};
struct variable2 rtpSenderEntry_variables[] = {
    { RTPSENDERCNAME, ASN_OCTET_STR, RONLY, read_rtpSenderEntry, 1, {2} },
    { RTPSENDERADDR, ASN_OCTET_STR, RONLY, read_rtpSenderEntry, 1, {3} },
    { RTPSENDERPACKETS, ASN_INTEGER, RONLY, read_rtpSenderEntry, 1, {4} },
    { RTPSENDEROCTETS, ASN_INTEGER, RONLY, read_rtpSenderEntry, 1, {5} },
    { RTPSENDERTOOL, ASN_OCTET_STR, RONLY, read_rtpSenderEntry, 1, {6} },
    { RTPSENDERSRS, ASN_INTEGER, RONLY, read_rtpSenderEntry, 1, {7} },
    { RTPSENDERSRTIME, ASN_INTEGER, RONLY, read_rtpSenderEntry, 1, {8} },
    { RTPSENDERPT, ASN_INTEGER, RONLY, read_rtpSenderEntry, 1, {9} },
    { RTPSENDERSTARTTIME, ASN_INTEGER, RONLY, read_rtpSenderEntry, 1, {10} },
};


void init_rtp_sender_group(void)
{
    REGISTER_MIB("rtpSenderInverseEntry", rtpSenderInverseEntry_variables,
         variable2, rtpSenderInverseEntry_oid);
    REGISTER_MIB("rtpSenderEntry", rtpSenderEntry_variables,
         variable2, rtpSenderEntry_oid);
}

#endif /* RTP_SENDER_GROUP */
