//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / TESTING MTP3
//
//File: mtptestmain.cpp
//
//Version: $Revision: 1.13 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/11/16 13:37:20 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Pärnänen
//
//Description:
//      Mainfile for MTP3 testing program.
//
//Copyright:
//
//
//Licence:
//
//
//History: 

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

#include "pf/system.h"
#include "pf/conduit.h"
#include "pf/protocol.h"
#include "pf/transp.h"
#include "pf/mux.h"
#include "pf/bytes.h"
#include "pf/debug.h"
#include "common/ss7configure.h"

#include "iface/naalif/naaldownprimitives.h"
#include "iface/mtpif/mtpdownprimitives.h"

#include "mtptest.h"

#include "protocol/mtp3/mtp3protocol.h"
#include "protocol/mtp3/mtp3config.h"

#include "protocol/saal/saalnnilink.h"

//------------------------------------------------------------------------

void printUsage(char *name_)
{
    cerr << endl;
    cerr << "Usage: " << name_
         << " [p PORT] [v VCI] [c PC] [a ACK] [t TRACE]" << endl << endl;
    cerr << "- PORT  = Port number" << endl;
    cerr << "- VCI   = Virtual Channel Identifier" << endl;
    cerr << "- PC    = Point Code (own point code of MTP3 protocol)" << endl;
    cerr << "- ACK   = Send acknowledge to messenger in upAdapter" << endl;
    cerr << "- TRACE = Trace printing" << endl;
    cerr << endl;
    cerr << "Default values: PORT = 0, VCI = 101, PC = 10" << endl;
    cerr << "                ACK = 0 (false), TRACE = 0 (false)" << endl;
    exit(0);
}

int main(int argc, char *argv[])
{
    const pfKey SCCP = 3;

    int count = 1;

    pfUlong PORT = 0;
    pfUlong VCI = 101;
    string pointCode("10");
    pfUlong PC = 10;
    pfBoolean ACK = 0;
    pfBoolean TRACE = 0;

    while (count < argc)
    {
        switch (*argv[count++])
        {
            case 'p':
              PORT = atoi(argv[count]);
              break;
            case 'v':
              VCI = atoi(argv[count]);
              break;
            case 'c':
              pointCode = argv[count];
              PC = atoi(pointCode.c_str());
	      break;
            case 'a':
              ACK = atoi(argv[count]);
	      break;
            case 't':
              TRACE = atoi(argv[count]);
	      debugOutputCout();
	      break;
            case 'h':
              printUsage(argv[0]);
              break;
            default: 
              break;
	}
	count++;
    }

    pfSystem::init(argc, argv);

    // Initialize variables
    pfId id = 0;
    pfKey maxValue = 1000;
    
    // SS7 configure object
    ss7Configure configure = 
        ss7ConfigureImplementation::createSS7Configure();
    configure.setPointCode(PC);

    configure.configureRoutingTable(10, 14, 1); // PC 10-14 => AALid 1

    // Create implementations

    saalNNIlink *link = saalNNIlink::createATMNNIlink(id, PORT, 0, VCI);
    link->setN1(1);  // Only one proving-PDUs
    pfConduit nsscfProxy = link->getConduit();

    pfConduit mtp3Proxy(mtp3Protocol::createProtocol(configure));
    mtpTestUpAdapter *upAdapter = new mtpTestUpAdapter(pointCode, ACK);	
    pfConduit upAdapterProxy(upAdapter);

    string SI("serviceIndicator");
    pfConduit userMuxProxy = pfMux::createMux(maxValue, SI);
    string AAL("AALid");
    pfConduit aalMuxProxy = pfMux::createMux(maxValue, AAL);

    // Set ids
    userMuxProxy.setId(id);
    aalMuxProxy.setId(id);    

    mtp3Proxy.setId(id);
    upAdapterProxy.setId(id);

    // Connect conduits
    aalMuxProxy.connectToA(mtp3Proxy);
    userMuxProxy.connectToA(mtp3Proxy);

    mtp3Proxy.connectToB(userMuxProxy);
    mtp3Proxy.connectToA(aalMuxProxy);

    if (TRACE != 0)
    {
	nsscfProxy.setTraceOn();
	userMuxProxy.setTraceOn();
	aalMuxProxy.setTraceOn(); 
	mtp3Proxy.setTraceOn();
	upAdapterProxy.setTraceOn();
    }

    // Connect user parts
    configure.setSCCP();

    mtpConfigTransporter config =
        mtpConfigTransporter::createConfigSideB(SCCP, upAdapterProxy);
    mtp3Proxy.accept(&config);

    // Connect sub systems
    configure.setTCAP();
    configure.setINAP();
    
    // Connect AAL connections
    mtpConfigTransporter config1 =
        mtpConfigTransporter::createConfigSideA(1, nsscfProxy);
    mtp3Proxy.accept(&config1);

    // Set up SAAL connection
    naalSTARTreq *startMessenger = new naalSTARTreq;
    pfMsgTransporter *startMessage = 
        pfMsgTransporter::createMsgTransporter(startMessenger);
    startMessage->setSender(aalMuxProxy);

    cout << "Setup SAAL NNI link" << endl;  

    nsscfProxy.accept(startMessage);


    // RUN
    pfSystem::instance()->run();

    return 0;
}

