//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / CPCS-to-socket adapter
//
//File: cpcsastate.cpp
//
//Version: $Revision: 1.10 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/09/02 06:50:03 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications and Multimedia
//
//Author:
//      Juhana Räsänen
//
//Description:
//      See corresponding header file
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 
//

#include <assert.h>
#include "cpcsastate.h"
#include "iface/cpcsif/cpcsdownprimitives.h"
#include "pf/device.h"
#include "pf/frame.h"
#include "pf/debug.h"

//
// Variable: cpcsActiveState :: _only
// Function: cpcsActiveState :: instance()
//
// Description:
//     Implement the singleton pattern used for actual states
//

cpcsActiveState *cpcsActiveState :: _only = 0;

cpcsActiveState *cpcsActiveState :: instance(void)
{
    if (_only == 0)
    {
        _only = new cpcsActiveState;
        assert(_only != 0);
    }
    return _only;
}


cpcsActiveState :: cpcsActiveState(void)
    : cpcsState()
{
    return;
}


cpcsActiveState :: ~cpcsActiveState(void)
{
    _only = 0;
    return;
}


//
// Function: cpcsActiveState :: cpcsUNITDATAreqAct()
//
// Description:
//     Write data in CPCS-UNITDATA.requests to the socket device in the
//     adapter. If write fails, re-queue data request.
//

void cpcsActiveState :: cpcsUNITDATAreqAct(cpcsUNITDATAreq *messenger_,
                                           pfProtocol *protocol_) const
{
    pfDevice *adapter = (pfDevice *) protocol_;
    pfFrame frame = messenger_->getInterfaceData();
    adapter->setAddr(messenger_->getAddress());

    if ((frame.length()) == 0)
    {
        debugUser("cpcsActiveState::cpcsUNITDATAreqAct frame length 0");
    }

    // If write returns a nonzero value, something went wrong.
    if (adapter->writeDevice(frame) != 0)
    {
        // Create a new cpcsUNITDATAreq messenger (the old one will get
        // deleted after this call returns) and put it to the head of the
        // message queue so that the order of the requests stays intact.
        cpcsUNITDATAreq *msg = new cpcsUNITDATAreq;
        msg->setInterfaceData(frame);
        msg->setSaveMethodToHead();
        msg->setAddress(adapter->getAddr());
        adapter->accept(msg);
        debugUser("cpcsActiveState :: cpcsUNITDATAreqAct: writeDevice failed");
    }
    
    return;
}

