//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: gsmpadjacencySYNSENTstate.cpp 
//
//State: $State: Exp $
//
//Version: $Revision: 1.12 $
//
//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:
//
//

class gsmpAdjacencySYNSENTstate;

#include "gsmpadjacencySYNSENTstate.h"
#include "gsmpadjacencyprotocol.h"
#include "gsmpinternalmessages.h"
#include "pf/error.h"

gsmpAdjacencySYNSENTstate *gsmpAdjacencySYNSENTstate::_only = 0;

//
// Function: gsmpAdjacencySYNSENTstate
//
// Description:
//     Constructor
//

gsmpAdjacencySYNSENTstate :: gsmpAdjacencySYNSENTstate(void)
{
    return;
}

//
// Function: ~gsmpAdjacencySYNSENTstate
//
// Description:
//     Destructor
//

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

//
// Function: instance
//
// Description:  
//

gsmpAdjacencySYNSENTstate *gsmpAdjacencySYNSENTstate :: instance(void)
{
    if (_only == 0)
    {
        _only = new gsmpAdjacencySYNSENTstate;
    }
    return _only;
}

//
// Function: gsmpAdjacencySYNCtimeoutAct
//
// Description:
//     Action if Adjacency Protocol SYNC timeout occurs
//

void gsmpAdjacencySYNSENTstate :: gsmpAdjacencySYNCtimeoutAct(
    gsmpAdjacencyProtocol *protocol_)
{
    protocol_->startTimer();
    protocol_->releaseACKlock();
    protocol_->sendAdjacencyProtocolSYNmessage();
    return;
}
//
// Function: gsmpAdjacencyRetryTimeoutAct
//
// Description:
//     Action if Adjacency Protocol Retry timeout occurs
//

void gsmpAdjacencySYNSENTstate :: gsmpAdjacencyRetryTimeoutAct(
    gsmpAdjacencyProtocol *protocol_)
{
    protocol_->resyncFailed();
    return;
}

//
// Function: gsmpAdjacencyProtocolSYNmessageAct
//
// Description:
//     Action for Adjacency Protocol SYN Message
//
  
void gsmpAdjacencySYNSENTstate :: gsmpAdjacencyProtocolSYNmessageAct(
    gsmpAdjacencyProtocolSYNmessage *message_,
    pfProtocol *protocol_)
{
    gsmpAdjacencyProtocol *protocol = dynamic_cast<gsmpAdjacencyProtocol *>(
        protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);

    // If SYNC timer is not active, start it to achieve the synchronization
    if (protocol->isTimerActive() == 0)
    {
        protocol->startTimer();
    }
    protocol->updateLastReceivedData(message_);
    protocol->updatePeerVerifier(message_);
    protocol->sendAdjacencyProtocolSYNACKmessage();
    protocol->stopRetryTimer();
    protocol->toAdjacencySYNRCVDstate();
    return;
}

//
// Function: gsmpAdjacencyProtocolSYNACKmessageAct
//
// Description:
//     Action for Adjacency Protocol SYNACK Message
//

void gsmpAdjacencySYNSENTstate :: gsmpAdjacencyProtocolSYNACKmessageAct(
    gsmpAdjacencyProtocolSYNACKmessage *message_,
    pfProtocol *protocol_)
{
    gsmpAdjacencyProtocol *protocol = dynamic_cast<gsmpAdjacencyProtocol *>(
        protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    protocol->updateLastReceivedData(message_);
    if (protocol->conditionC(message_) != 0)
    {
        protocol->updatePeerVerifier(message_);
        protocol->sendAdjacencyProtocolACKmessage();
        protocol->startResyncTimer();
        protocol->stopRetryTimer();
        protocol->toAdjacencyESTABstate();

        // Send gsmpLinkEstablished to GSMP
        protocol->sendGsmpLinkEstablished();
    }
    else // if ((protocol->conditionC(message_)) == 0)
    {
        protocol->sendAdjacencyProtocolRSTACKmessage();
    }
    return;
}

//
// Function: gsmpAdjacencyProtocolACKmessageAct
//
// Description:
//     Action for Adjacency Protocol ACK Message
//

void gsmpAdjacencySYNSENTstate :: gsmpAdjacencyProtocolACKmessageAct(
    gsmpAdjacencyProtocolACKmessage *message_,
    pfProtocol *protocol_)
{
    gsmpAdjacencyProtocol *protocol = dynamic_cast<gsmpAdjacencyProtocol *>(
        protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    protocol->updateLastReceivedData(message_);
    protocol->sendAdjacencyProtocolRSTACKmessage();
    return;
}

//
// Function: gsmpAdjacencyRSTACKmessageAct
//
// Description:
//     Action for Adjacency Protocol RSTACK Message
//

void gsmpAdjacencySYNSENTstate :: gsmpAdjacencyProtocolRSTACKmessageAct(
    gsmpAdjacencyProtocolRSTACKmessage *message_,
    pfProtocol *protocol_)
{
    // Discard the message
    gsmpAdjacencyProtocol *protocol = dynamic_cast<gsmpAdjacencyProtocol *>(
        protocol_);
    THROW_IF_DYNAMIC_CAST_FAILED(protocol);
    protocol->updateLastReceivedData(message_);
    return;
}

//
// Function: sendNonAdjacencyMessage
//
// Description:
//     This method checks the result field from incoming GSMP Protocol
//     Message. Because link is not established, message will be discarded

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