//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: gsmpconnectionmanagementmessages.cpp
//
//State: $State: Exp $
//
//Version: $Revision: 1.5 $
//
//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 "gsmpconnectionmanagementmessages.h"
#include "gsmpstate.h"
#include "gsmpexceptions.h"
#include "pf/error.h"

//
// Function: gsmpConnectionManagement
//
// Description:  
//     Default constructor
//

gsmpConnectionManagementMessage :: gsmpConnectionManagementMessage(void)
    : gsmpMessage(),
      _portSessionNumber(0),
      _inputPort(0),
      _inputVPI(0),
      _inputVCI(0),
      _outputPort(0),
      _outputVPI(0),
      _outputVCI(0),
      _numberOfBranches(0),
      _priority(0)
{
    return;
}

//
// Function: gsmpConnectionManagement
//
// Description:  
//     Copy constructor
//

gsmpConnectionManagementMessage :: gsmpConnectionManagementMessage(
    const gsmpConnectionManagementMessage &other_)
    : gsmpMessage(other_),
      _portSessionNumber(other_._portSessionNumber),
      _inputPort(other_._inputPort),
      _inputVPI(other_._inputVPI),
      _inputVCI(other_._inputVCI),
      _outputPort(other_._outputPort),
      _outputVPI(other_._outputVPI),
      _outputVCI(other_._outputVCI),
      _numberOfBranches(other_._numberOfBranches),
      _priority(other_._priority)
{
    return;
}

//
// Function: ~gsmpConnectionManagement
//
// Description:  
//     Destructor
//

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

//
// Function: decodeFrame
//
// Description:  
//     Default method to decode a frame to a connection management message.
//     This method applies to all connection management messages except
//     gsmpMoveBranchMessage.
//

void gsmpConnectionManagementMessage :: decodeFrame(pfFrame &frame_)
{
    _frame = frame_;
    _version = frame_.getFirst();
    _messageType = frame_.getFirst();
    _result = frame_.getFirst();
    _code = frame_.getFirst();
    _transactionIdentifier = frame_.getFirst32bit();
    _portSessionNumber = frame_.getFirst32bit();
    _inputPort = frame_.getFirst32bit();
    _inputVPI = (frame_.getFirst16bit() & gsmpMessage::GSMP_VPI_MASK);
    _inputVCI = frame_.getFirst16bit();
    _outputPort = frame_.getFirst32bit();
    _outputVPI = frame_.getFirst16bit();
    _outputVCI = frame_.getFirst16bit();
    _numberOfBranches = frame_.getFirst16bit();
    frame_.getFirst();
    _priority = frame_.getFirst();
    if (frame_.length() != 0)
    {
        throw gsmpInvalidLengthException(PF_EX_INFO);
    }
    return;
}

//
// Function: encodeFrame
//
// Description:  
//     Default method to encode a connection management message to a frame.
//     This method applies to all connection management messages except
//     gsmpMoveBranchMessage.
//

pfFrame gsmpConnectionManagementMessage :: encodeFrame(void)
{
    _frame.clear();
    _frame.putLast(_version);
    _frame.putLast(_messageType);
    _frame.putLast(_result);
    _frame.putLast(_code);
    _frame.putLast32bit(_transactionIdentifier);
    _frame.putLast32bit(_portSessionNumber);
    _frame.putLast32bit(_inputPort);
    _frame.putLast16bit(_inputVPI & gsmpMessage::GSMP_VPI_MASK);
    _frame.putLast16bit(_inputVCI);
    _frame.putLast32bit(_outputPort);
    _frame.putLast16bit(_outputVPI & gsmpMessage::GSMP_VPI_MASK);
    _frame.putLast16bit(_outputVCI);
    _frame.putLast16bit(_numberOfBranches);
    _frame.putLast(0);
    _frame.putLast(_priority);
    return _frame;
}

//
// Functions: Get
//
// Description:
//     These methods return the message data
//

pfUlong gsmpConnectionManagementMessage :: getPortSessionNumber(void) const
{
    return _portSessionNumber;
}

pfUlong gsmpConnectionManagementMessage :: getInputPort(void) const
{
    return _inputPort;
}

pfUlong gsmpConnectionManagementMessage :: getInputVPI(void) const
{
    return _inputVPI;
}

pfUlong gsmpConnectionManagementMessage :: getInputVCI(void) const
{
    return _inputVCI;
}

pfUlong gsmpConnectionManagementMessage :: getOutputPort(void) const
{
    return _outputPort;
}

pfUlong gsmpConnectionManagementMessage :: getOutputVPI(void) const
{
    return _outputVPI;
}

pfUlong gsmpConnectionManagementMessage :: getOutputVCI(void) const
{
    return _outputVCI;
}

pfUlong gsmpConnectionManagementMessage :: getNumberOfBranches(void) const
{
    return _numberOfBranches;
}

pfByte gsmpConnectionManagementMessage :: getPriority(void) const
{
    return _priority;
}

//
// Function: setPortSessionNumber
//
// Description:
//     Set the _portSessionNumber of the message
//

void gsmpConnectionManagementMessage :: setPortSessionNumber(
    pfUlong portSessionNumber_)
{
    _portSessionNumber = portSessionNumber_;
}

//
// Function: gsmpAddBranchMessage
//
// Description:
//     Default constructor
//

gsmpAddBranchMessage :: gsmpAddBranchMessage(void)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::ADD_BRANCH;
    return;
}

//
// Function: gsmpAddBranchMessage
//
// Description:
//     Constructor
//

gsmpAddBranchMessage :: gsmpAddBranchMessage(pfByte result_,
                                             pfUlong transactionIdentifier_,
                                             pfUlong portSessionNumber_,
                                             pfUlong inputPort_,
                                             pfUlong inputVPI_,
                                             pfUlong inputVCI_,
                                             pfUlong outputPort_,
                                             pfUlong outputVPI_,
                                             pfUlong outputVCI_,
                                             pfByte priority_)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::ADD_BRANCH;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _portSessionNumber = portSessionNumber_;
    _inputPort = inputPort_;
    _inputVPI = inputVPI_;
    _inputVCI = inputVCI_;
    _outputPort = outputPort_;
    _outputVPI = outputVPI_;
    _outputVCI = outputVCI_;
    _priority = priority_;
    return;
}

//
// Function: gsmpAddBranchMessage
//
// Description:
//     Copy constructor
//

gsmpAddBranchMessage::gsmpAddBranchMessage(const gsmpAddBranchMessage &other_)
    : gsmpConnectionManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpAddBranchMessage
//
// Description:
//     Destructor
//

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

//
// Function: clone
//
// Description:
//

gsmpAddBranchMessage *gsmpAddBranchMessage :: clone(void)
{
    gsmpAddBranchMessage *message = new gsmpAddBranchMessage(*this);
    return message;
}

//
// Function: apply
//
// Description:
//

void gsmpAddBranchMessage :: apply(pfState *state_, pfProtocol *protocol_)
{
    gsmpState *state = dynamic_cast<gsmpState*>(state_);
    THROW_IF_DYNAMIC_CAST_FAILED(state);
    state->gsmpAddBranchMessageAct(this, protocol_); 
    return;
}

//
// Function: gsmpDeleteBranchMessage
//
// Description:
//     Default constructor
//

gsmpDeleteBranchMessage :: gsmpDeleteBranchMessage(void)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::DELETE_BRANCH;
    return;
}

//
// Function: gsmpDeleteBranchMessage
//
// Description:
//     Constructor
//

gsmpDeleteBranchMessage :: gsmpDeleteBranchMessage(
    pfByte result_,
    pfUlong transactionIdentifier_,
    pfUlong portSessionNumber_,
    pfUlong inputPort_,
    pfUlong inputVPI_,
    pfUlong inputVCI_,
    pfUlong outputPort_,
    pfUlong outputVPI_,
    pfUlong outputVCI_)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::DELETE_BRANCH;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _portSessionNumber = portSessionNumber_;
    _inputPort = inputPort_;
    _inputVPI = inputVPI_;
    _inputVCI = inputVCI_;
    _outputPort = outputPort_;
    _outputVPI = outputVPI_;
    _outputVCI = outputVCI_;
    return;
}

//
// Function: gsmpDeleteBranchMessage
//
// Description:
//     Copy constructor
//

gsmpDeleteBranchMessage :: gsmpDeleteBranchMessage(
    const gsmpDeleteBranchMessage &other_)
    : gsmpConnectionManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpDeleteBranchMessage
//
// Description:
//     Destructor
//

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

//
// Function: clone
//
// Description:
//     

gsmpDeleteBranchMessage *gsmpDeleteBranchMessage :: clone(void)
{
    gsmpDeleteBranchMessage *message = new gsmpDeleteBranchMessage(*this);
    return message;
}

//
// Function: apply
//
// Description:
//     

void gsmpDeleteBranchMessage :: apply(pfState *state_, pfProtocol *protocol_)
{
    gsmpState *state = dynamic_cast<gsmpState*>(state_);
    THROW_IF_DYNAMIC_CAST_FAILED(state);
    state->gsmpDeleteBranchMessageAct(this, protocol_); 
    return;
}

//
// Function: gsmpDeleteTreeMessage
//
// Description:
//     Default constructor
//

gsmpDeleteTreeMessage :: gsmpDeleteTreeMessage(void)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::DELETE_TREE;
    return;
}

//
// Function: gsmpDeleteTreeMessage
//
// Description:
//     Constructor
//

gsmpDeleteTreeMessage :: gsmpDeleteTreeMessage(pfByte result_,
                                               pfUlong transactionIdentifier_,
                                               pfUlong portSessionNumber_,
                                               pfUlong inputPort_,
                                               pfUlong inputVPI_,
                                               pfUlong inputVCI_)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::DELETE_TREE;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _portSessionNumber = portSessionNumber_;
    _inputPort = inputPort_;
    _inputVPI = inputVPI_;
    _inputVCI = inputVCI_;
    return;
}

//
// Function: gsmpDeleteTreeMessage
//
// Description:
//     Copy constructor
//

gsmpDeleteTreeMessage :: gsmpDeleteTreeMessage(
    const gsmpDeleteTreeMessage &other_)
    : gsmpConnectionManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpDeleteTreeMessage
//
// Description:
//     Destructor
//

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

//
// Function: clone
//
// Description:
//     

gsmpDeleteTreeMessage *gsmpDeleteTreeMessage :: clone(void)
{
    gsmpDeleteTreeMessage *message = new gsmpDeleteTreeMessage(*this);
    return message;
}

//
// Function: apply
//
// Description:
//     

void gsmpDeleteTreeMessage :: apply(pfState *state_, pfProtocol *protocol_)
{
    gsmpState *state = dynamic_cast<gsmpState*>(state_);
    THROW_IF_DYNAMIC_CAST_FAILED(state);
    state->gsmpDeleteTreeMessageAct(this, protocol_); 
    return;
}

//
// Function: gsmpVerifyTreeMessage
//
// Description:
//     Default constructor
//

gsmpVerifyTreeMessage :: gsmpVerifyTreeMessage(void)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::VERIFY_TREE;
    return;
}

//
// Function: gsmpVerifyTreeMessage
//
// Description:
//     Constructor
//

gsmpVerifyTreeMessage :: gsmpVerifyTreeMessage(pfByte result_,
                                               pfUlong transactionIdentifier_,
                                               pfUlong portSessionNumber_,
                                               pfUlong inputPort_,
                                               pfUlong inputVPI_,
                                               pfUlong inputVCI_,
                                               pfUlong numberOfBranches_)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::VERIFY_TREE;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _portSessionNumber = portSessionNumber_;
    _inputPort = inputPort_;
    _inputVPI = inputVPI_;
    _inputVCI = inputVCI_;
    _numberOfBranches = numberOfBranches_;
    return;
}

//
// Function: gsmpVerifyTreeMessage
//
// Description:
//     Copy constructor
//

gsmpVerifyTreeMessage :: gsmpVerifyTreeMessage(
    const gsmpVerifyTreeMessage &other_)
    : gsmpConnectionManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpVerifyTreeMessage
//
// Description:
//     Destructor
//

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

//
// Function: clone
//
// Description:
//     

gsmpVerifyTreeMessage *gsmpVerifyTreeMessage :: clone(void)
{
    gsmpVerifyTreeMessage *message = new gsmpVerifyTreeMessage(*this);
    return message;
}

//
// Function: apply
//
// Description:
//     

void gsmpVerifyTreeMessage :: apply(pfState *state_, pfProtocol *protocol_)
{
    gsmpState *state = dynamic_cast<gsmpState*>(state_);
    THROW_IF_DYNAMIC_CAST_FAILED(state);
    state->gsmpVerifyTreeMessageAct(this, protocol_); 
    return;
}

//
// Function: gsmpDeleteAllMessage
//
// Description:
//     Default constructor
//

gsmpDeleteAllMessage :: gsmpDeleteAllMessage(void)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::DELETE_ALL;
    return;
}

//
// Function: gsmpDeleteAllMessage
//
// Description:
//     Constructor
//

gsmpDeleteAllMessage :: gsmpDeleteAllMessage(pfByte result_,
                                             pfUlong transactionIdentifier_,
                                             pfUlong portSessionNumber_,
                                             pfUlong inputPort_)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::DELETE_ALL;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _portSessionNumber = portSessionNumber_;
    _inputPort = inputPort_;
    return;
}

//
// Function: gsmpDeleteAllMessage
//
// Description:
//     Copy constructor
//

gsmpDeleteAllMessage::gsmpDeleteAllMessage(const gsmpDeleteAllMessage &other_)
    : gsmpConnectionManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpDeleteAllMessage
//
// Description:
//     Destructor
//

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

//
// Function: clone
//
// Description:
//     

gsmpDeleteAllMessage *gsmpDeleteAllMessage :: clone(void)
{
    gsmpDeleteAllMessage *message = new gsmpDeleteAllMessage(*this);
    return message;
}

//
// Function: apply
//
// Description:
//     

void gsmpDeleteAllMessage :: apply(pfState *state_, pfProtocol *protocol_)
{
    gsmpState *state = dynamic_cast<gsmpState*>(state_);
    THROW_IF_DYNAMIC_CAST_FAILED(state);
    state->gsmpDeleteAllMessageAct(this, protocol_); 
    return;
}

//
// Function: gsmpMoveBranchMessage
//
// Description:
//     Default constructor
//

gsmpMoveBranchMessage :: gsmpMoveBranchMessage(void)
    : gsmpConnectionManagementMessage(),
      _oldOutputPort(0),
      _oldOutputVPI(0),
      _oldOutputVCI(0),
      _newOutputPort(0),
      _newOutputVPI(0),
      _newOutputVCI(0)
{
    _messageType = gsmpConnectionManagementMessage::MOVE_BRANCH;
    return;
}

//
// Function: gsmpMoveBranchMessage
//
// Description:
//     Constructor
//

gsmpMoveBranchMessage :: gsmpMoveBranchMessage(pfByte result_,
                                               pfUlong transactionIdentifier_,
                                               pfUlong portSessionNumber_,
                                               pfUlong inputPort_,
                                               pfUlong inputVPI_,
                                               pfUlong inputVCI_,
                                               pfUlong oldOutputPort_,
                                               pfUlong oldOutputVPI_,
                                               pfUlong oldOutputVCI_,
                                               pfUlong newOutputPort_,
                                               pfUlong newOutputVPI_,
                                               pfUlong newOutputVCI_,
                                               pfByte priority_)
    : gsmpConnectionManagementMessage()
{
    _messageType = gsmpConnectionManagementMessage::MOVE_BRANCH;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _portSessionNumber = portSessionNumber_;
    _inputPort = inputPort_;
    _inputVPI = inputVPI_;
    _inputVCI = inputVCI_;
    _oldOutputPort = oldOutputPort_;
    _oldOutputVPI = oldOutputVPI_;
    _oldOutputVCI = oldOutputVCI_;
    _newOutputPort = newOutputPort_;
    _newOutputVPI = newOutputVPI_;
    _newOutputVCI = newOutputVCI_;
    _priority = priority_;
    return;
}

//
// Function: gsmpMoveBranchMessage
//
// Description:
//     Copy constructor
//

gsmpMoveBranchMessage :: gsmpMoveBranchMessage(
    const gsmpMoveBranchMessage &other_)
    : gsmpConnectionManagementMessage(other_),
      _oldOutputPort(other_._oldOutputPort),
      _oldOutputVPI(other_._oldOutputVPI),
      _oldOutputVCI(other_._oldOutputVCI),
      _newOutputPort(other_._newOutputPort),
      _newOutputVPI(other_._newOutputVPI),
      _newOutputVCI(other_._newOutputVCI)
{
    return;
}

//
// Function: ~gsmpMoveBranchMessage
//
// Description:
//     Destructor
//

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

//
// Function: decodeFrame
//
// Description:
//     This method decodes a frame to a gsmpMoveBranchMessage
//

void gsmpMoveBranchMessage :: decodeFrame(pfFrame &frame_)
{
    _frame = frame_;
    _version = frame_.getFirst();
    _messageType = frame_.getFirst();
    _result = frame_.getFirst();
    _code = frame_.getFirst();
    _transactionIdentifier = frame_.getFirst32bit();
    _portSessionNumber = frame_.getFirst32bit();
    _inputPort = frame_.getFirst32bit();
    _inputVPI = (frame_.getFirst16bit() & gsmpMessage::GSMP_VPI_MASK);
    _inputVCI = frame_.getFirst16bit();
    _oldOutputPort = frame_.getFirst32bit();
    _oldOutputVPI = (frame_.getFirst16bit() & gsmpMessage::GSMP_VPI_MASK);
    _oldOutputVCI = frame_.getFirst16bit();
    _newOutputPort = frame_.getFirst32bit();
    _newOutputVPI = (frame_.getFirst16bit() & gsmpMessage::GSMP_VPI_MASK);
    _newOutputVCI = frame_.getFirst16bit();
    frame_.getFirst24bit();
    _priority = frame_.getFirst();
    if (frame_.length() != 0)
    {
        throw gsmpInvalidLengthException(PF_EX_INFO);
    }
    return;
}

//
// Function: encodeFrame
//
// Description:
//     This method encodes a gsmpMoveBranchMessage to a frame
//

pfFrame gsmpMoveBranchMessage :: encodeFrame(void)
{
    _frame.clear();
    _frame.putLast(_version);
    _frame.putLast(_messageType);
    _frame.putLast(_result);
    _frame.putLast(_code);
    _frame.putLast32bit(_transactionIdentifier);
    _frame.putLast32bit(_portSessionNumber);
    _frame.putLast32bit(_inputPort);
    _frame.putLast16bit(_inputVPI & gsmpMessage::GSMP_VPI_MASK);
    _frame.putLast16bit(_inputVCI);
    _frame.putLast32bit(_oldOutputPort);
    _frame.putLast16bit(_oldOutputVPI & gsmpMessage::GSMP_VPI_MASK);
    _frame.putLast16bit(_oldOutputVCI);
    _frame.putLast32bit(_newOutputPort);
    _frame.putLast16bit(_newOutputVPI & gsmpMessage::GSMP_VPI_MASK);
    _frame.putLast16bit(_newOutputVCI);
    _frame.putLast24bit(0);
    _frame.putLast(_priority);
    return _frame;
}

//
// Function: clone
//
// Description:
//     

gsmpMoveBranchMessage *gsmpMoveBranchMessage :: clone(void)
{
    gsmpMoveBranchMessage *message = new gsmpMoveBranchMessage(*this);
    return message;
}

//
// Function: apply
//
// Description:
//     

void gsmpMoveBranchMessage :: apply(pfState *state_, pfProtocol *protocol_)
{
    gsmpState *state = dynamic_cast<gsmpState*>(state_);
    THROW_IF_DYNAMIC_CAST_FAILED(state);
    state->gsmpMoveBranchMessageAct(this, protocol_); 
    return;
}

//
// Functions: Get
//
// Description:
//     These methods return the message data
//     

pfUlong gsmpMoveBranchMessage :: getOldOutputPort(void) const
{
    return _oldOutputPort;
}

pfUlong gsmpMoveBranchMessage :: getOldOutputVPI(void) const
{
    return _oldOutputVPI;
}

pfUlong gsmpMoveBranchMessage :: getOldOutputVCI(void) const
{
    return _oldOutputVCI;
}

pfUlong gsmpMoveBranchMessage :: getNewOutputPort(void) const
{
    return _newOutputPort;
}

pfUlong gsmpMoveBranchMessage :: getNewOutputVPI(void) const
{
    return _newOutputVPI;
}

pfUlong gsmpMoveBranchMessage :: getNewOutputVCI(void) const
{
    return _newOutputVCI;
}
