//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / TCAP
//
//File: tcaptestmain.cpp
//
//Version: $Revision: 1.16 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/11/05 16:30:03 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Pärnänen
//
//Description:
//
//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/sccpif/sccpdownprimitives.h"
#include "iface/naalif/naaldownprimitives.h"
#include "protocol/tcap/tcapadapter.h"
#include "protocol/sccp/sccpprotocol.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] [c PC] [v VCI] [t TRACE]" << endl;
    cerr << "- PORT  = Port number" << endl;
    cerr << "- PC    = Point Code (own point code of MTP3 protocol)" << endl;
    cerr << "- VCI   = Virtual Channel Identifier" << endl;
    cerr << "- TRACE = Trace printing" << endl;
    cerr << endl;
    cerr << "Default values: PORT = 0, PC = 10, VCI = 50, TRACE = 1 (true)" << endl;
    exit(0);
}

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

    int count = 1;

    pfUlong PORT = 0;
    pfUlong VCI = 101;
    pfUlong PC = 1;
    pfBoolean TRACE = 1;

    if (argc%2 == 0)
    {
        printUsage(argv[0]);
    }

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

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


    string GT_1("SSP");
    string GT_2("SCP");
    string GT_3("SCE");
    
    if (PC == 1)
    {
        configure.addGTtoPCandSSN(GT_2, 2, 11); // 11 = INAP
        configure.addGTtoPCandSSN(GT_3, 2, 11); // 11 = INAP
    }
    else if (PC == 2)
    {
        configure.addGTtoPCandSSN(GT_1, 1, 11); // 11 = INAP
    }
    else
    {
	debugUser("SCCP tranformation table not configured");
    }
    configure.configureRoutingTable(1, 2, 1); // PC 1-2 => AALid 1


    pfSystem::init(argc, argv);

    //
    // Create implementations and proxies
    //

    pfConduit tcapProxy = tcapAdapter::createTCAP(PC);

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

    pfConduit mtp3Proxy(mtp3Protocol::createProtocol(configure));
    pfConduit sccpProxy = sccpProtocol::createProtocol(configure);

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

    // Set ids
    tcapProxy.setId(id);

    userMuxProxy.setId(id);
    aalMuxProxy.setId(id);    

    mtp3Proxy.setId(id);
    sccpProxy.setId(id);

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

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

    sccpProxy.connectToB(tcapProxy);
    tcapProxy.connectToA(sccpProxy);

    // Connect user parts
    configure.setSCCP();

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

    // Connect sub systems
    configure.setTCAP();
    configure.setINAP();
    
    // Connect AAL connections
    mtpConfigTransporter config1 =
        mtpConfigTransporter::createConfigSideA(1, nsscfProxy);
    // mtpConfigTransporter config2 =
    //    mtpConfigTransporter::createConfigSideA(2, AAL2_Proxy);

    mtp3Proxy.accept(&config1);
    //mtp3Proxy.accept(&config2);

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

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

    return 0;
}
