//
// Derived from the Hello example of OmniBroker 1.0
//

#include <errno.h>
#include <OB/CORBA.h>
#include <OB/Util.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_FSTREAM
#   include <fstream>
#else
#   include <fstream.h>
#endif
#include <string>
#include "aa_adapter_impl.h"
#include "pf/system.h"
#include "sscoplink.h"
#include "iface/aaif/aadownprimitives.h"

aaAdapter_impl *setupConduits(int port_, int vci_);

int main(int argc, char* argv[], char*[])
{
    pfSystem::init(argc, argv);
    try
    {
        if (argc != 3)
        {
            cerr << "Usage: " << argv[0] << " port vci" << endl;
            exit(0);
        }

        int port = atoi(argv[1]);
        int vci = atoi(argv[2]);

	//
	// Create implementation object
	//
        aaAdapter_impl *obj = setupConduits(port, vci);
	aaAdapter_var p(obj);
	
	//
	// Save reference
	//
	CORBA_String_var s = pfSystem::instance()->getORB()->object_to_string(p);
	const char* refFile = "SSCOP.ref";

        //
        // NOTE: use C FILEs rather than C++ file streams, because the
        // latter don't work with g++ when RTTI is in use
        //
        FILE *fp = fopen(refFile, "w");
        if(fp == 0)
	{
	    cerr << argv[0] << ": can't open `" << refFile << "': "
		 << strerror(errno) << endl;
	    return 1;
	}
	
        fprintf(fp, "%s\n", s.in());
        fclose(fp);
	
	//
	// Run implementation (DON'T call impl_is_ready!)
	//
        pfSystem::instance()->run();
    }
#ifdef __GNUG__
    catch(CORBA_COMM_FAILURE& ex)
#else
    catch(CORBA_SystemException& ex)
#endif
    {
	OBPrintException(ex);
	return 1;
    }

    return 0;
}


//
// Function: setupConduits
//
// Description:
//     Instantiates the conduit tree for this SSCOP test server:
//
//
//            ___ IDL for inject()
//      _______|______              ______________  ----------------------
//      \  aaAdapter /              \  pfAdapter /--| aaSinkAdapterState |
//       ------------                ------------   ----------------------
//             |                          |
//      ---------------            ---------------
//      |    SSCOP    |            |    SSCOP    |
//      ---------------            ---------------
//             |                          |
//       ------------                ------------
//      / cpcsAdapter\              / cpcsAdapter\
//      --------------              --------------
//             |                          |
//             |       ATM AAL5 link      |
//             - - - - - - - - - - - - - --
//
//     This server contains the leftmost conduit stack, the rightmost
//     one is contained in a separate sink process. Client process can
//     call the IDL interface of the aaAdapter and request transmission
//     of a given number of PDUs with given interval (in msecs) between
//     each PDU. The adapter does this by sending AA-DATA.request
//     primitives to the SSCOP instance. The contents of the data
//     is a small message and the total length of one message is
//     1024 octets. The receiver process prints the contents of each
//     received message before discarding them.
//

aaAdapter_impl *setupConduits(int port_, int vci_)
{
    sscopLink *link = sscopLink::createATMSSCOPlink(0, port_, 0, vci_);
    pfConduit sc = link->getConduit();
    sc.setTraceOn();

    aaAdapter_impl *a = new aaAdapter_impl;
    pfConduit ac(a);
    ac.setId(0);

    sc.connectToB(ac);
    ac.connectToA(sc);

    // Open the SSCOP connection
    aaESTABLISHreq *msg = new aaESTABLISHreq;
    a->toA(msg);

    return a;
}

