//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: gsmpswitchmain.cpp
//
//Version: $Revision: 1.1 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/08/03 11:40:43 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author: Timo Pärnänen
//
//
//Description:
//    Main program for switchsimulator (PC-gsmpswitch).
//
//Copyright:
//
//
//Licence:
//
//
//History: 

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

#include "sf/exception.h"
#include "pf/system.h"
#include "pf/types.h"
#include "pf/conduit.h"
#include "pf/system.h"
#include "pf/newtrace.h"
#include "pf/exception.h"

#include "common/atmsockdev.h"
#include "trace/texttrace.h"

#include "protocol/cpcs/cpcsaadapter.h"
#include "protocol/gsmp/gsmpadjacencyprotocol.h"
#include "protocol/gsmp/gsmpprotocol.h"
#include "protocol/gsmp/gsmpfactory.h"
#include "protocol/gsmp/gsmpprimitives.h"

#include "protocol/gsmpswitch/gsmpswitchprotocol.h"

//
//Function definiton
// 

void setupGsmpSwitchProtocol(int port_, int vci_, pfBoolean trace_);

//
//Function: main
//

int main(int argc, char *argv[])
{
    pfUlong PORT = 0;
    pfUlong VCI = 50;
    pfBoolean TRACE = 0;

    try
    {
        // Setup GSMP Protocol
        cout << "Setting up gsmpSwitch Protocol" << endl;
        setupGsmpSwitchProtocol(PORT, VCI, TRACE);
        
        // Run the system
        cout << "running..." << endl << endl;
        pfSystem::instance()->run();
    }
    catch (sfException &exception)
    {
        exception.printInfo();
    }
    catch (pfException &exception)
    {
        exception.printInfo();
    }
    return 0;
}


//
//Function: setupGsmpSwitchProtocol 
//

void setupGsmpSwitchProtocol(int port_, int vci_, pfBoolean trace_)
{
    pfId id = 1;

    // Trace definitions
    if (trace_ != 0)
    {
        pfNewTrace::instance()->setTrace(tvTextTrace::create(), id);
    }

    // Socket Device for the signalling VCI
    pfDevice *cpcs = 0;
    tvATMSocketDevice *atm = new cpcsATMAdapter(1500);
    assert(atm != 0);
    atm->openDevice(port_, 0, vci_);
    cpcs = atm;

    // GSMP protocol
    pfConduit gsmpSwitchProxy;
    try
    {
        gsmpSwitchProxy =  gsmpSwitchProtocol::create();
    }

    // Adjacency Protocol
    pfConduit adjacencyProxy;
    try
    {
        adjacencyProxy = gsmpAdjacencyProtocol::create(port_);
    }
    catch (pfException &exception)
    {
        exception.printInfo();
        throw;
    }

    cpcs->readDevice();

    pfConduit cpcsProxy(cpcs);
    cpcsProxy.setId(id);
    adjacencyProxy.setId(id);
    gsmpSwitchProxy.setId(id);
    // Set trace on
    if (trace_ != 0)
    {
        cpcsProxy.setTraceOn();
        adjacencyProxy.setTraceOn();
    } 

    // Connect Conduits
    gsmpSwitchProxy.connectToA(adjacencyProxy);
    adjacencyProxy.connectToB(gsmpSwitchProxy);
    adjacencyProxy.connectToA(cpcsProxy);
    cpcsProxy.connectToA(adjacencyProxy);
    
    // Start Adjacency Protocol
    gsmpStartAdjacencyProtocol *transporter =
        gsmpStartAdjacencyProtocol::createGsmpStartAdjacencyProtocol();
    if (transporter == 0)
    {
        throw pfMemoryAllocationException(PF_EX_INFO,
                                          sizeof(gsmpStartAdjacencyProtocol));
    }
    cout << "Starting GSMP Protocol..." << endl;
    adjacencyProxy.accept(transporter);
    return;
}
