//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: gsmptest.cpp
//
//Version: $Revision: 1.6 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/12/16 15:27:36 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Harri Sunila
//
//Description:
//      A simple program to test GSMP. Now only tests if Adjacency Protocol
//      works. Creates separate CPCS-adapter and Adjcency Protocol conduits
//      and interconnects them. Starts the Adjacency Protocol to send SYN
//      message on specific VPI/VCI pair in specific port.
//
//Copyright:
//
//
//Licence:
//
//
//History: 

#include <typeinfo>
#include <iostream.h>
#include <string>
#include "pf/conduit.h"
#include "pf/system.h"
#include "pf/debug.h"
#include "pf/atmsocket.h"
#include "protocol/gsmp/gsmpadjacencyprotocol.h"
#include "protocol/cpcs/cpcsaadapter.h"
#include "protocol/gsmp/gsmpdefs.h"
#include <assert.h>
#include <unistd.h>
#include "pf/exception.h"
#include "sf/exception.h"
#include "protocol/gsmp/gsmpprimitives.h"

// Tracing not possible

void setupAdjacencyProtocol(int port_,
                            int vci_,
                            int trace_)
{
    pfId id = 1;
    // Socket Device for the signalling VCI
    pfDevice *cpcs = 0;
    pfATMsocket *atm = new cpcsATMAdapter(GSMP_MTU);
    assert(atm != 0);
    atm->openDevice(port_, 0, vci_);
    cpcs = atm;

    // 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);

    // Set trace on
    if (trace_ != 0)
    {
        cpcsProxy.setTraceOn();
	adjacencyProxy.setTraceOn();
    } 

    // Connect Conduits
    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 Adjacency Protocol..." << endl;
    adjacencyProxy.accept(transporter);
    
    return;
}

void usage(const char *name_)
{
    cerr << "Usage: " << name_
         << " [t] [p] [v VCI]" << endl;
    cerr << "       t: Trace on" << endl;
    cerr << "       p: Port" << endl;
    cerr << "       v: Use given VCI" << endl;
    cerr << endl;
    exit(0);
    return;
}

int main(int argc, char *argv[])
{
    if (argc < 1)
    {
        usage(argv[0]);
    }
	   
    pfSystem::init(argc, argv);

    int count = 1;

    int port = 0;
    int vci = 15;
    int trace = 0;
    
    while (count < argc)
    {
        switch (*argv[count])
	{
	    case 't':
	      trace = 1;
	      debugOutputCout();
	      break;
            case 'p':
              count++;
              if (count == argc)
              {
                  usage(argv[0]);
              }
              port = atoi(argv[count]);
              break;

	    case 'v':
	      count++;
	      if (count == argc)
	      {
		  usage(argv[0]);
	      }
	      vci = atoi(argv[count]);
	      break;
	    default:
	      usage(argv[0]);
	      break;
	}
	count++;
    }
    
    try
    {
        // Setup Adjacency Protocol
        cout << "Setting up AdjacencyProtocol" << endl;
	setupAdjacencyProtocol(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;
}
