//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / CPCS module
//
//File: cpcsaadapter.cpp
//
//Version: $Revision: 1.11 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/12/16 13:55:11 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Juhana Räsänen
//
//Description:
//      See the corresponding header file
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 
//

#include <typeinfo>
#include "cpcsaadapter.h"
#include "cpcsstate.h"
#include "cpcsastate.h"
#include "iface/cpcsif/cpcsupprimitives.h"
#include "pf/frame.h"
#include "pf/debug.h"
#include "pf/error.h"

//
//Function: createATMConnection
//
//Description:
//    Create a new ATM connection in CPCS protocol layer.
//

pfConduit cpcsATMAdapter :: createATMConnection(int port_,
                                                int vpi_,
                                                int vci_,
                                                pfUlong sduSize_)
{
    cpcsATMAdapter *atm = new cpcsATMAdapter(sduSize_);
    if (atm->openDevice(port_, vpi_, vci_) != 0 ||
        atm->readDevice() != 0)
    {
        delete atm;
        THROW_NETWORK_OUT_OF_ORDER;
    }
    pfConduit cpcsProxy(atm);
    return cpcsProxy;
}

//
//Function: cpcsATMAdapter constructors
//
//Description:
//    Create a new instance of cpcsATMAdapter class and changes its
//    state to active state.
//

cpcsATMAdapter :: cpcsATMAdapter(pfUlong sduSize_)
    : pfATMsocket(sduSize_)
{

#ifdef DEBUG
    clearDebug();
#endif // DEBUG

    changeState(cpcsActiveState::instance());
    return;
}

pfProtocol * cpcsATMAdapter :: cloneImplementation(void) const
{
    return 0;
}

//
//Function: cpcsATMAdapter destructor
//
//Description:
//      Do nothing
//

cpcsATMAdapter :: ~cpcsATMAdapter(void)
{
    return;
}

//
//Function: readAction
//
//Description:
//    Method that gets called from the socket device when a read request
//    has triggered, ie there is a received message available.
//    A frame has been received from the lower layer (SAR protocol,
//    AAL5 socket etc.) The data gets passed via parameter and a new
//    cpcsUNITDATAind messenger is made of it and it is sent to the
//    Conduit side A.
//    Code parameter has the result code from socket device, currently
//    it is not examined only written along frame contents as a debug
//    message, if debugging is enabled.
//

void cpcsATMAdapter :: readAction(pfFrame &frame_, pfUlong code_)
{
#ifdef DEBUG
    if (_debug != 0)
    {
        debugFrame("Frame", frame_);
        debugPfUlong("Code", code_);
    }
#endif // DEBUG

    // Send a data indication only if there is something in the frame.
    // If the frame is empty, an error occured inside the device and an
    // indication probably should be given to some management object.
    if (frame_.length() > 0)
    {
        cpcsUNITDATAind *message = new cpcsUNITDATAind;
        assert(message != 0);
        message->setInterfaceData(frame_);
        toA(message);
    }
    else
    {
        // ++TODO++ Notify layer management of the error
    }
    readDevice();
    return;
}

//
//Function: writeAction
//
//Description:
//    Method that gets called from the socket device when a write request
//    has ended and data has supposedly been written to the socket.
//

void cpcsATMAdapter :: writeAction(pfUlong code_)
{
    return;
}

#ifdef DEBUG

//
//Function: setDebug
//
//Description:
//    Sets the debug flag to enable debugging.
//

void cpcsATMAdapter :: setDebug(void)
{
    _debug = 1;
    return;
}

//
//Function: clearDebug
//
//Description:
//    Clears the debug flag to disable debugging.
//

void cpcsATMAdapter :: clearDebug(void)
{
    _debug = 0;
    return;
}

//
//Function: debugActive
//
//Description:
//    Returns the debug status of the adapter.
//

bool cpcsATMAdapter :: debugActive(void) const
{
    return _debug;
}

#endif // DEBUG

