//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: gsmpadjacencystate.cpp
//
//State: $State: Exp $
//
//Version: $Revision: 1.6 $
//
//Date: $Date: 1998/12/16 16:57:24 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
// 
//Author:
//      Harri Sunila
//
//Description:
//      See corresponding header file
//
//Copyright:    
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999 
//      
//Licence:
//     
//
//History:
//
//

#include "gsmpadjacencystate.h"
#include "gsmpadjacencyprotocolmessage.h"
#include "gsmpconfigurationmessages.h"
#include "gsmpconnectionmanagementmessages.h"
#include "gsmpportmanagementmessages.h"
#include "gsmpstatisticsmessages.h"
#include "gsmpeventmessages.h"
#include "gsmpadjacencyprotocol.h"
#include "pf/transp.h"
#include "pf/factory.h"
#include "gsmpprimitives.h"
#include "pf/error.h"

//
// Function: gsmpAdjacencyState
//
// Description:
//     Constructor
//

gsmpAdjacencyState::gsmpAdjacencyState(void)
    : gsmpState(),
      cpcsUpInputs()
{
    return;
}

//
// Function: ~gsmpAdjacencyState 
//
// Description:
//     Destructor
//

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

//
// Function: resetTheLink
//
// Description:
//     This function has been described in RFC 1987 page 37. Function
//     generates a new instance number for the link. It sets to zero
//     the Sender Instance, Sender Port and Sender Name previously stored by
//     Update Peer Ferifier operation (described in RFC). Protocol sends
//     a SYN message and enters the SYNSENT state.
//

void gsmpAdjacencyState::resetTheLink(pfProtocol *protocol_)
{
    gsmpAdjacencyProtocol *protocol = dynamic_cast<gsmpAdjacencyProtocol *>(
        protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    protocol->generateNewInstanceNumber();
    protocol->resetPeerVerifier();
    protocol->sendAdjacencyProtocolSYNmessage();
    protocol->toAdjacencySYNSENTstate();
    protocol->startTimer();
    return;
}

//
// Function: gsmpAdjacencySYNCtimeoutAct
//
// Description:
//     Action if SYNC timeout occurs. 
//

void gsmpAdjacencyState::gsmpAdjacencySYNCtimeoutAct(
    gsmpAdjacencyProtocol *protocol_)
{
    return;
}

//
// Function: gsmpAdjacencyResyncTimeoutAct
//
// Description:
//     Action if the synchronizations has been lost
//

void gsmpAdjacencyState :: gsmpAdjacencyResyncTimeoutAct(
    gsmpAdjacencyProtocol *protocol_)
{
    return;
}

//
// Function: gsmpAdjacencyRetryTimeoutAct
//
// Description:
//     Action if the resynchronizations has failed
//

void gsmpAdjacencyState :: gsmpAdjacencyRetryTimeoutAct(
    gsmpAdjacencyProtocol *protocol_)
{
    return;
}

//
// Function: gsmpAdjacencyProtocolXXmessageAct
//
// Description:
//     Action when an Adjacency Protocol Message comes into Protocol.
//     Different Adjacency Protocol Messages differs from another message only 
//     by the code field.

//
// Function: gsmpAdjacencyProtocolSYNmessageAct
//
// Description:
//     Specific action for Adjacency Protocol SYN Message
//

void gsmpAdjacencyState::gsmpAdjacencyProtocolSYNmessageAct(
    gsmpAdjacencyProtocolSYNmessage *message_,
    pfProtocol *protocol_)
{
    return;
}

//
// Function: gsmpAdjacencyProtocolSYNACKmessageAct
//
// Description:
//     Specific action for Adjacency Protocol SYNACK Message
//

void gsmpAdjacencyState::gsmpAdjacencyProtocolSYNACKmessageAct(
    gsmpAdjacencyProtocolSYNACKmessage *message_,
    pfProtocol *protocol_)
{
    return;
}

//
// Function: gsmpAdjacencyProtocolACKmessageAct
//
// Description:
//     Specific action for Adjacency Protocol ACK Message
//

void gsmpAdjacencyState::gsmpAdjacencyProtocolACKmessageAct(
    gsmpAdjacencyProtocolACKmessage *message_,
    pfProtocol *protocol)
{
    return;
}

//
// Function: gsmpAdjacencyRSTACKmessageAct
//
// Description:
//     Specific action for Adjacency Protocol RSTACK Message
//

void gsmpAdjacencyState::gsmpAdjacencyProtocolRSTACKmessageAct(
    gsmpAdjacencyProtocolRSTACKmessage *message_,
    pfProtocol *protocol)
{
    return;
}

//
// Function: cpcsUNITDATAindAct
//
// Description:
//     Action for incoming CPCS-UNITADA.indication primitives from
//     CPCS-Adapter. This method creates the correct GSMP messenger according
//     the frame of the incoming messenger and sends it to the Adjacency
//     Protocol protocol instance.
//

void gsmpAdjacencyState::cpcsUNITDATAindAct(cpcsUNITDATAind *messenger_,
                                            pfProtocol *protocol_) const
{
    gsmpMessage *message;
    try
    {
        message = gsmpMessage::create(messenger_->getInterfaceData());
    }
    catch (pfException &exception)
    {
        exception.printInfo();
        return;
    }
    pfMsgTransporter *msg = pfMsgTransporter::createMsgTransporter(message);
    protocol_->accept(msg);
    return;
}

// Following methods are for GSMP Protocol Messages which have entered the
// either from upper GSMP Protocol or from CPCS-Adapter. These methods may
// be implemented partially if all GSMP functionality is not needed.

void gsmpAdjacencyState::gsmpAddBranchMessageAct(
    gsmpAddBranchMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpDeleteBranchMessageAct(
    gsmpDeleteBranchMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpDeleteTreeMessageAct(
    gsmpDeleteTreeMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpVerifyTreeMessageAct(
    gsmpVerifyTreeMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpDeleteAllMessageAct(
    gsmpDeleteAllMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpMoveBranchMessageAct(
    gsmpMoveBranchMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

// Port Management Messages

void gsmpAdjacencyState::gsmpBringUpMessageAct(gsmpBringUpMessage *message_,
                                               pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpTakeDownMessageAct(gsmpTakeDownMessage *message_,
                                                pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpInternalLoopbackMessageAct(
    gsmpInternalLoopbackMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpExternalLoopbackMessageAct(
    gsmpExternalLoopbackMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpBothwayLoopbackMessageAct(
    gsmpBothwayLoopbackMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpResetInputPortMessageAct(
    gsmpResetInputPortMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpResetEventFlagsMessageAct(
    gsmpResetEventFlagsMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

// Statistics Messages
  
void gsmpAdjacencyState::gsmpVCActivityRequestMessageAct(
    gsmpVCActivityRequestMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpVCActivityResponseMessageAct(
    gsmpVCActivityResponseMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpPortStatisticsRequestMessageAct(
    gsmpPortStatisticsRequestMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpPortStatisticsResponseMessageAct(
    gsmpPortStatisticsResponseMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpVCStatisticsRequestMessageAct(
    gsmpVCStatisticsRequestMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpVCStatisticsResponseMessageAct(
    gsmpVCStatisticsResponseMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

 // Configuration Messages

void gsmpAdjacencyState::
gsmpSwitchConfigurationRequestMessageAct(
    gsmpSwitchConfigurationRequestMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpPortConfigurationRequestMessageAct(
    gsmpPortConfigurationRequestMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpAllPortsConfigurationRequestMessageAct(
    gsmpAllPortsConfigurationRequestMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpSwitchConfigurationResponseMessageAct(
    gsmpSwitchConfigurationResponseMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpPortConfigurationResponseMessageAct(
    gsmpPortConfigurationResponseMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpAllPortsConfigurationResponseMessageAct(
    gsmpAllPortsConfigurationResponseMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

// Event Messages

void gsmpAdjacencyState::gsmpPortUpEventMessageAct(
    gsmpPortUpEventMessage *message_,
    pfProtocol *protocol_)
{
  sendNonAdjacencyMessage(message_, protocol_);
  return;
}

void gsmpAdjacencyState::gsmpPortDownEventMessageAct(
    gsmpPortDownEventMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpInvalidVPIVCIEventMessageAct(
    gsmpInvalidVPIVCIEventMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpNewPortEventMessageAct(
    gsmpNewPortEventMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

void gsmpAdjacencyState::gsmpDeadPortEventMessageAct(
    gsmpDeadPortEventMessage *message_,
    pfProtocol *protocol_)
{
    sendNonAdjacencyMessage(message_, protocol_);
    return;
}

//
// Function: sendNonAdjacencyMessage
//
// Description:
//     Send a GSMP message either to the upper GSMP conduit or to the switch.
//     This method is virtual and therefore must be implemented in the derived
//     classes.
//

void gsmpAdjacencyState::sendNonAdjacencyMessage(gsmpMessage *message_,
                                                 pfProtocol *protocol_)
{
  return;
}
