//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / ILMI
//
//File: codertest.cpp
//
//Version: $Revision: 1.1 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/06/03 17:50:33 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Pärnänen
//
//Description:
//      Test program for SNACC generated ASN.1 BER coders for
//      SNMP messages.
//
//Copyright:
//
//
//Licence:
//
//
//History: 

#include <typeinfo>
#include <iostream.h>
#include <string>

#include <asn-incl.h>
#include "asn/rfc1155-smi.h"
#include "asn/rfc1157-snmp.h"
#include "asn/rfc1213-mib2.h"

void decode(AsnBuf inputBuffer_);


// This program encodes and decodes one SNMP message
// carrying GetResponsePDU inside.

//
// main function
//

int main(void)
{
    //
    // Message 
    //
    Message message;
    
    message.version = MessageInt(MessageInt::version_1);
    message.community = AsnOcts("ILMI");

    //
    // Data
    //
    PDUs *data = new PDUs();
    data->choiceId = PDUs::get_responseCid;

    //
    // PDU
    //
    GetResponse_PDU *pdu = new GetResponse_PDU();

    pdu->request_id = 1;
    pdu->error_status = PDUInt(PDUInt::noError);
    pdu->error_index = AsnInt(0);

    //
    // VarBindList
    //
    VarBindList varList;
    VarBind *var1 = varList.Append();
    VarBind *var2 = varList.Append();    
    
    //
    // VarBind Values (1)
    //
    ObjectName name1 = sysObjectID;

    SimpleSyntax *simple1 = new SimpleSyntax();
    simple1->choiceId = SimpleSyntax::numberCid;
    simple1->number = new AsnInt(1234);
    
    ObjectSyntax *value1 = new ObjectSyntax();
    value1->choiceId = ObjectSyntax::simpleCid;
    value1->simple = simple1;
    
    //
    // VarBind Values (2)
    //
    ObjectName
name2(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21);

    SimpleSyntax *simple2 = new SimpleSyntax();
    simple2->choiceId = SimpleSyntax::stringCid;
    simple2->string = new AsnOcts("Terve");    
    
    ObjectSyntax *value2 = new ObjectSyntax();
    value2->choiceId = ObjectSyntax::simpleCid;
    value2->simple = simple2;
      
    //
    // Set name/value pairs to VarBind
    //  
    var1->name = name1;
    var1->value = value1;

    var2->name = name2;
    var2->value = value2;

    //
    // Set VarBindList into PDU and PDU into data (PDus) and
    // data into Message.
    //
    pdu->variable_bindings = varList;
    data->get_response = pdu;
    message.data = data;
    
    //
    // Print Message content
    //
    message.Print(cout);

    //
    // Encode
    //    
    AsnBuf outputBuf;
    size_t encodedLen;

    int dataSize = 1024;
    char dataBuf[1024];
    
    // set up buffer for writing to
    outputBuf.Init(dataBuf, dataSize);
    outputBuf.ResetInWriteRvsMode();

    if (!message.BEncPdu(outputBuf, encodedLen))
    {
        cerr << "Encoding failed !!" << endl;
        exit(0);
    }
    
    cout << "\nEncoding success !!" << endl;
    cout << "EncodedLength: " << encodedLen << endl;
    outputBuf.ResetInReadMode();

    // Dynamic created objects SHOULD be deleted !!
    
    //
    // Decode
    //
    decode(outputBuf);
    return 0;
}

void decode(AsnBuf inputBuffer_)
{
    Message message;
    size_t decodedLen;

    if (!message.BDecPdu(inputBuffer_, decodedLen))
    {
        cerr << "ERROR - Decode routines failed, exiting..." << endl;
        exit(1);
    }
    
    cout << "\nDecoding success !!" << endl;
    cout << "DecodedLength: " << decodedLen << endl;
    cout  << "\nMessage ::= " << message << endl;

    if (message.data->choiceId != PDUs::get_responseCid)
    {
        cerr << "NOT GET_RESPONSE_PDU" << endl;
        exit(1);
    }

    GetResponse_PDU *pdu = message.data->get_response;
    
    //
    // Use OIDs
    //
    cout << "\n------ Use OIDs --------" << endl;
    VarBindList &list = pdu->variable_bindings;
    list.SetCurrToFirst();
    cout << "Number or VarBinds = " << list.Count() << endl << endl;

    VarBind *var;
    for(int i=0; i<list.Count(); i++, list.GoNext())
    {
        var = list.Curr();        
        cout << "Name(" << i << "): " << var->name << endl;

        //
        // AsnOid-luokasta saadaan const-pointteri long int
        // vektoriin, johon AsnOid on dekoodattu.
        //
        const long int *oid = var->name.getOid();
        int j=0;

        // Huom !! Lopetusehtona vektorin tulostukselle :
        //         alkion arvo suurempi kuin nolla.

        while(oid[j] > 0)
        {
            cout << "oid[" << j << "] = " << oid[j] << ", ";
            j++; 
        }
        cout << endl << endl;
        oid = 0;
    }
    return;
}
