//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: gsmpprotocolstate.cpp 
//
//Version: $Revision: 1.9 $
//
//State: $State: Exp $
//
//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 headerfile. 
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 

#include "gsmpprotocolstate.h"
#include "gsmpprotocol.h"
#include "gsmpinternalmessages.h"
#include "gsmpconnectionmanagementmessages.h"
#include "gsmpconfigurationmessages.h"
#include "gsmpeventmessages.h"
#include "gsmpport.h"
#include "pf/error.h"

gsmpProtocolState :: gsmpProtocolState(void)
{
    return;
}

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

void gsmpProtocolState :: gsmpResponseTimeoutAct(gsmpResponseTimeout *timeout_,
                                                 gsmpProtocol *protocol_)
{
    pfUlong transactionIdentifier = timeout_->getTransactionIdentifier();
    protocol_->gsmpResponseTimeoutOccured(transactionIdentifier);
    return;
}

//
// Function: gsmpAddBranchMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpAddBranchMessageAct(
    gsmpAddBranchMessage *message_,
    pfProtocol *protocol_)
{
    processConnectionManagementMessage(message_, protocol_);
    return;
}

//
// Function: gsmpDeleteBranchMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpDeleteBranchMessageAct(
    gsmpDeleteBranchMessage *message_,
    pfProtocol *protocol_)
{
    processConnectionManagementMessage(message_, protocol_);
    return;
}

//
// Function: gsmpDeleteTreeMessageAct
//
// Description:  
//
    
void gsmpProtocolState :: gsmpDeleteTreeMessageAct(
    gsmpDeleteTreeMessage *message_,
    pfProtocol *protocol_)
{
    processConnectionManagementMessage(message_, protocol_);
    return;
}

//
// Function: gsmpVerifyTreeMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpVerifyTreeMessageAct(
    gsmpVerifyTreeMessage *message_,
    pfProtocol *protocol_)
{
    processConnectionManagementMessage(message_, protocol_);
    return;
}

//
// Function: gsmpDeleteAllMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpDeleteAllMessageAct(
    gsmpDeleteAllMessage *message_,
    pfProtocol *protocol_)
{
    processConnectionManagementMessage(message_, protocol_);
    return;
}

//
// Function: gsmpMoveBranchMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpMoveBranchMessageAct(
    gsmpMoveBranchMessage *message_,
    pfProtocol *protocol_)
{
    processConnectionManagementMessage(message_, protocol_);
    return;
}

//
// Function: gsmpBringUpMessageAct
//
// Description:  
//

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

//
// Function: gsmpTakeDownMessageAct
//
// Description:  
//

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


//
// Function: gsmpInternalLoopbackMessageAct
//
// Description:  
//

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

//
// Function: gsmpExternalLoopbackMessageAct
//
// Description:  
//

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

//
// Function: gsmpBothwayLoopbackMessageAct
//
// Description:  
//

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

//
// Function: gsmpResetInputPortMessageAct 
//
// Description:  
//

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

//
// Function: gsmpResetEventFlagsMessageAct
//
// Description:  
//

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

//
// Function: gsmpVCActivityRequestMessageAct
//
// Description:  
//
    
void gsmpProtocolState :: gsmpVCActivityRequestMessageAct(
    gsmpVCActivityRequestMessage *message_,
    pfProtocol *protocol_)
{
    return;
}

//
// Function: gsmpVCActivityResponseMessageAct
//
// Description:  
//
    
void gsmpProtocolState :: gsmpVCActivityResponseMessageAct(
    gsmpVCActivityResponseMessage *message_,
    pfProtocol *protocol_)
{
    return;
}

//
// Function: gsmpPortStatisticsRequestMessageAct 
//
// Description:  
//

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

//
// Function: gsmpPortStatisticsResponseMessageAct 
//
// Description:  
//

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

//
// Function: gsmpVCStatisticsRequestMessageAct
//
// Description:  
//

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

//
// Function: gsmpVCStatisticsResponseMessageAct
//
// Description:  
//

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

//
// Function: gsmpSwitchConfigurationRequestMessageAct
//
// Description:  
//

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

//
// Function: gsmpSwitchConfigurationResponseMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpSwitchConfigurationResponseMessageAct(
    gsmpSwitchConfigurationResponseMessage *message_,
    pfProtocol *protocol_)
{
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    pfUlong transactionIdentifier = message_->getTransactionIdentifier();
    protocol->removeTimer(transactionIdentifier);
    protocol->acceptResponse(transactionIdentifier, message_);
    return;
}

//
// Function: gsmpPortConfigurationRequestMessageAct
//
// Description:  
//

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

//
// Function: gsmpPortConfigurationResponseMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpPortConfigurationResponseMessageAct(
    gsmpPortConfigurationResponseMessage *message_,
    pfProtocol *protocol_)
{
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    pfByte result = message_->getResult();
    pfUlong transactionIdentifier = message_->getTransactionIdentifier();
    protocol->removeTimer(transactionIdentifier);
    pfUlong port = message_->getPort();

    pfUlong portSessionNumber = message_->getPortSessionNumber();
    pfByte portStatus = message_->getPortStatus();
    pfByte lineStatus = message_->getLineStatus();

    // Set the current configuration
    if ((result == gsmpMessage::GSMP_SUCCESS) &&
        (portStatus == gsmpPort::GSMP_PORT_AVAILABLE) &&
        (lineStatus == gsmpPort::GSMP_LINE_UP))
    {
        protocol->setPortSessionNumber(port, portSessionNumber);
    }
    
    // Accept the response. Note that if the request is sent by GSMP itself,
    // acceptResponse() does not find a proxy and destroys the messenger.
    protocol->acceptResponse(transactionIdentifier, message_);
    return;
}

//
// Function: gsmpAllPortsConfigurationRequestMessageAct
//
// Description:  
//

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

//
// Function: gsmpAllPortsConfigurationResponseMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpAllPortsConfigurationResponseMessageAct(
    gsmpAllPortsConfigurationResponseMessage *message_,
    pfProtocol *protocol_)
{
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    pfByte result = message_->getResult();
    pfUlong transactionIdentifier = message_->getTransactionIdentifier();
    protocol->removeTimer(transactionIdentifier);

    pfUlong port, portSessionNumber;
    pfByte portStatus, lineStatus;
    
    vector<gsmpPortRecord> portRecords(message_->getPortRecords());
    vector<gsmpPortRecord>::iterator i, end;
    i = portRecords.begin();
    end = portRecords.end();
    while (i != end)
    {
        // Get the current configuration
        port = (*i).getPort();
        portSessionNumber = (*i).getPortSessionNumber();
        portStatus = (*i).getPortStatus();
        lineStatus = (*i).getLineStatus();

        // Set the current configuration
        if ((result == gsmpMessage::GSMP_SUCCESS) &&
            (portStatus == gsmpPort::GSMP_PORT_AVAILABLE) &&
            (lineStatus == gsmpPort::GSMP_LINE_UP))
        {
            protocol->setPortSessionNumber(port, portSessionNumber);
        }

        i++;
    }
    
    // Accept the response. Note that if the request is sent by GSMP itself,
    // acceptResponse() does not find a proxy and destroys the messenger.
    protocol->acceptResponse(transactionIdentifier, message_);
    return;
}

//
// Function: gsmpPortUpEventMessageAct
//
// Description:  
//

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

//
// Function: gsmpPortDownEventMessageAct
//
// Description:  
//

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

//
// Function: gsmpInvalidVPIVCIEventMessageAct
//
// Description:  
//

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

//
// Function: gsmpNewPortEventMessageAct
//
// Description:  
//

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

//
// Function: gsmpDeadPortEventMessageAct
//
// Description:  
//

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

//
// Function: gsmpListenEventsMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpListenEventsMessageAct(
    gsmpListenEventsMessage *message_,
    pfProtocol *protocol_)
{
    pfUlong transactionIdentifier;
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    transactionIdentifier = message_->getTransactionIdentifier();
    protocol->registerEventListener(transactionIdentifier);
    return;
}

//
// Function: gsmpForgetEventsMessageAct
//
// Description:  
//

void gsmpProtocolState :: gsmpForgetEventsMessageAct(
    gsmpForgetEventsMessage *message_,
    pfProtocol *protocol_)
{
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    protocol->unRegisterEventListener(message_);
    return;
}

//
// Function: gsmpLinkEstablishedAct
//
// Description:
//     Change GSMP to active state. Send a notification also as an event.
//

void gsmpProtocolState :: gsmpLinkEstablishedAct(gsmpLinkEstablished *message_,
                                                 pfProtocol *protocol_)
{
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);

    // Change state before notification
    protocol->toGsmpActiveState();
    protocol->acceptEvent(message_);
    return;
}

//
// Function: gsmpLinkNotEstablishedAct
//
// Description:
//     Change GSMP to active state. Send a notification also as an event.
//

void gsmpProtocolState :: gsmpLinkNotEstablishedAct(
    gsmpLinkNotEstablished *message_,
    pfProtocol *protocol_)
{
    gsmpProtocol *protocol = dynamic_cast<gsmpProtocol *>(protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);

    // Send notification before changing state
    protocol->acceptEvent(message_);
    protocol->toGsmpIdleState();
    return;
}

//
// Function: processConnectionManagementState
//
// Description:
//     Process a Connection Management message.
//

void gsmpProtocolState :: processConnectionManagementMessage(
    gsmpConnectionManagementMessage *message_,
    pfProtocol *protocol_)
{
    return;
}
