//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / CPCS module
//
//File: cpcsuadapter.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 "cpcsuadapter.h"
#include "cpcsstate.h"
#include "cpcsastate.h"
#include "iface/cpcsif/cpcsupprimitives.h"
#include "pf/frame.h"
#include "pf/debug.h"

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

pfConduit cpcsUDPAdapter :: createUDPConnection(string hostname_,
                                                int localPort_,
                                                int remotePort_,
                                                pfUlong sduSize_)
{
    cpcsUDPAdapter *udp = new cpcsUDPAdapter(sduSize_);
    udp->openDevice(hostname_, localPort_, remotePort_);
    udp->readDevice();
    pfConduit cpcsProxy(udp);
    return cpcsProxy;
}

//
//Function: cpcsUDPAdapter constructors
//
//Description:
//    Create a new instance of cpcsUDPAdapter class. The constructor does
//    not open a device for the adapter, it must be given separately
//    with setDevice method. The adapter activates itself automatically
//    from the first call to read() or write() by opening the device.
//

cpcsUDPAdapter :: cpcsUDPAdapter(pfUlong sduSize_)
    : pfUDPsocket(sduSize_)
{

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

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

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

//
//Function: cpcsUDPAdapter destructor
//
//Description:
//      Do nothing
//

cpcsUDPAdapter :: ~cpcsUDPAdapter(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 cpcsUDPAdapter :: 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_);
        message->setAddress(getAddr());
        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. State
//    machine method for this event gets called.
//

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

#ifdef DEBUG

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

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

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

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

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

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

#endif // DEBUG
