//Editor-Info: -*- C++ -*-
//
//Subject: GSMP
//
//File: gsmpportmanagementmessages.cpp
//
//Version: $Revision: 1.5 $
//
//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 header file
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//      
//Licence:
//     
//
//History:
//

#include "gsmpportmanagementmessages.h"
#include "gsmpexceptions.h"
#include "pf/error.h"

//
// Function: gsmpPortManagementMessage
//
// Description:
//   gsmpPortManagement base class costructor
//

gsmpPortManagementMessage :: gsmpPortManagementMessage(void)
    : gsmpMessage(),
      _port(0),
      _portSessionNumber(0),
      _eventSequenceNumber(0),  // this is ignored by the receiver
      _eventFlags(0x00),        // only used in the "Reset Event Flags" message
      _duration(0),             // only used in the loopback messages 
      _function(0)
{
    _messageType = PORT_MANAGEMENT; // right type
    return;
}

//
// Function: gsmpPortManagementMessage
//
// Description:
//   gsmpPortManagement base class copy costructor
//

gsmpPortManagementMessage :: gsmpPortManagementMessage(
    const gsmpPortManagementMessage &other_)
    : gsmpMessage(other_),
      _port(other_._port),
      _portSessionNumber(other_._portSessionNumber),
      _eventSequenceNumber(other_._eventSequenceNumber),
      _eventFlags(other_._eventFlags),
      _duration(other_._duration),
      _function(other_._function)
{
    return;
}

//
// Function: ~gsmpPortManagementMessage
//
// Description:
//   Destructor
//

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

//
// Function: encodeFrame
//
// Description:
//

pfFrame gsmpPortManagementMessage :: encodeFrame(void)
{
    _frame.clear();
    _frame.putLast(_version);
    _frame.putLast(_messageType);
    _frame.putLast(_result);
    _frame.putLast(_code);
    _frame.putLast32bit(_transactionIdentifier);
    _frame.putLast32bit(_port);
    _frame.putLast32bit(_portSessionNumber);
    _frame.putLast32bit(_eventSequenceNumber);
    _frame.putLast(_eventFlags);
    _frame.putLast(_duration);
    _frame.putLast16bit(_function);
    return _frame;
}

//
// Function: decodeFrame
//
// Description:
//

void gsmpPortManagementMessage :: decodeFrame(pfFrame &frame_)
{
    _frame = frame_;
    _version = frame_.getFirst();
    _messageType = frame_.getFirst();
    _result = frame_.getFirst();
    _code = frame_.getFirst();
    _transactionIdentifier = frame_.getFirst32bit();
    _port = frame_.getFirst32bit();
    _portSessionNumber = frame_.getFirst32bit();
    _eventSequenceNumber = frame_.getFirst32bit();
    _eventFlags = frame_.getFirst();
    _duration = frame_.getFirst();
    _function = frame_.getFirst16bit();
    if (frame_.length() != 0)
    {
        throw gsmpInvalidLengthException(PF_EX_INFO);
    }
    return;
}

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

pfUlong gsmpPortManagementMessage :: getPort(void) const
{
    return _port;
}

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

pfUlong gsmpPortManagementMessage :: getEventSequenceNumber(void) const
{
    return _eventSequenceNumber;
}

pfByte gsmpPortManagementMessage :: getEventFlags(void) const
{
    return _eventFlags;
}

pfByte gsmpPortManagementMessage :: getDuration(void) const
{
    return _duration;
}

pfUlong gsmpPortManagementMessage :: getFunction(void) const
{
    return _function;
}

//
// Function: gsmpBringUpMessage
//
// Description:
//     Default constructor
//

gsmpBringUpMessage :: gsmpBringUpMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::BRING_UP;
    return;
}

//
// Function: gsmpBringUpMessage
//
// Description:
//     Constructor
//

gsmpBringUpMessage :: gsmpBringUpMessage(pfByte result_,
                                         pfUlong transactionIdentifier_,
                                         pfUlong port_,
                                         pfUlong portSessionNumber_)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::BRING_UP;
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    return;
}

//
// Function: gsmpBringUpMessage
//
// Description:
//     Copy constructor
//

gsmpBringUpMessage :: gsmpBringUpMessage(const gsmpBringUpMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpBringUpMessage
//
// Description:
//     Destructor
//

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

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

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

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

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

//
// Function: gsmpTakeDownMessage
//
// Description:
//     Default constructor
//

gsmpTakeDownMessage :: gsmpTakeDownMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::TAKE_DOWN;
    return;
}

//
// Function: gsmpTakeDownMessage
//
// Description:
//     Constructor
//

gsmpTakeDownMessage :: gsmpTakeDownMessage(pfByte result_,
                                           pfUlong transactionIdentifier_,
                                           pfUlong port_,
                                           pfUlong portSessionNumber_)
    :gsmpPortManagementMessage()
{
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    _function = gsmpPortManagementMessage::TAKE_DOWN;
    return;
}

//
// Function: gsmpTakeDownMessage
//
// Description:
//     Copy constructor
//

gsmpTakeDownMessage :: gsmpTakeDownMessage(const gsmpTakeDownMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpTakeDownMessage
//
// Description:
//     Destructor
//

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

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

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

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

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

//
// Function: gsmpInternalLoopbackMessage
//
// Description:
//     Default constructor
//

gsmpInternalLoopbackMessage :: gsmpInternalLoopbackMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::INTERNAL_LOOPBACK;
    return;
}

//
// Function: gsmpInternalLoopbackMessage
//
// Description:
//     Constructor
//

gsmpInternalLoopbackMessage :: gsmpInternalLoopbackMessage(
    pfByte result_,
    pfUlong transactionIdentifier_,
    pfUlong port_,
    pfUlong portSessionNumber_,
    pfByte duration_)
    :gsmpPortManagementMessage()
{
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    _duration = duration_;
    _function = gsmpPortManagementMessage::INTERNAL_LOOPBACK;
    return;
}

//
// Function: gsmpInternalLoopbackMessage
//
// Description:
//     Copy constructor
//

gsmpInternalLoopbackMessage :: gsmpInternalLoopbackMessage(
    const gsmpInternalLoopbackMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: gsmpInternalLoopbackMessage
//
// Description:
//     Destructor
//

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

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

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

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

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

//
// Function: gsmpExternalLoopbackMessage
//
// Description:
//     Default constructor
//

gsmpExternalLoopbackMessage :: gsmpExternalLoopbackMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::EXTERNAL_LOOPBACK;
    return;
}

//
// Function: gsmpExternalLoopbackMessage
//
// Description:
//     Constructor
//

gsmpExternalLoopbackMessage :: gsmpExternalLoopbackMessage(
    pfByte result_,
    pfUlong transactionIdentifier_,
    pfUlong port_,
    pfUlong portSessionNumber_,
    pfByte duration_)
    :gsmpPortManagementMessage()
{
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    _duration = duration_;
    _function = gsmpPortManagementMessage::EXTERNAL_LOOPBACK;
    return;
}

//
// Function: gsmpExternalLoopbackMessage
//
// Description:
//     Copy constructor
//

gsmpExternalLoopbackMessage :: gsmpExternalLoopbackMessage(
    const gsmpExternalLoopbackMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpExternalLoopbackMessage
//
// Description:
//     Destructor
//

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

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

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

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

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

//
// Function: gsmpBothwayLoopbackMessage
//
// Description:
//     Default constructor
//

gsmpBothwayLoopbackMessage::gsmpBothwayLoopbackMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::BOTHWAY_LOOPBACK;
    return;
}

//
// Function: gsmpBothwayLoopbackMessage
//
// Description:
//     Constructor
//

gsmpBothwayLoopbackMessage::gsmpBothwayLoopbackMessage(
    pfByte result_,
    pfUlong transactionIdentifier_,
    pfUlong port_,
    pfUlong portSessionNumber_,
    pfByte duration_)
    :gsmpPortManagementMessage()
{
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    _duration = duration_;
    _function = gsmpPortManagementMessage::BOTHWAY_LOOPBACK;
    return;
}

//
// Function: gsmpBothwayLoopbackMessage
//
// Description:
//     Copy constructor
//

gsmpBothwayLoopbackMessage::gsmpBothwayLoopbackMessage(
    const gsmpBothwayLoopbackMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpBothwayLoopbackMessage
//
// Description:
//     Destructor
//

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

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

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

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

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

//
// Function: gsmpResetInputPortMessage
//
// Description:
//     Default constructor
//

gsmpResetInputPortMessage :: gsmpResetInputPortMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::RESET_INPUT_PORT;
    return;
}

//
// Function: gsmpResetInputPortMessage
//
// Description:
//     Constructor
//

gsmpResetInputPortMessage :: gsmpResetInputPortMessage(
    pfByte result_,
    pfUlong transactionIdentifier_,
    pfUlong port_,
    pfUlong portSessionNumber_)
    :gsmpPortManagementMessage()
{
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    _function = gsmpPortManagementMessage::RESET_INPUT_PORT;
    return;
}

//
// Function: gsmpResetInputPortMessage
//
// Description:
//     Copy constructor
//

gsmpResetInputPortMessage :: gsmpResetInputPortMessage(
    const gsmpResetInputPortMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: ~gsmpResetInputPortMessage
//
// Description:
//     Destructor
//

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

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

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

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

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

//
// Function: gsmpResetEventFlagsMessage
//
// Description:
//     Default constructor
//

gsmpResetEventFlagsMessage :: gsmpResetEventFlagsMessage(void)
    :gsmpPortManagementMessage()
{
    _function = gsmpPortManagementMessage::RESET_EVENT_FLAGS;
    return;
}

//
// Function: gsmpResetEventFlagsMessage
//
// Description:
//     Constructor
//

gsmpResetEventFlagsMessage :: gsmpResetEventFlagsMessage(
    pfByte result_,
    pfUlong transactionIdentifier_,
    pfUlong port_,
    pfUlong portSessionNumber_,
    pfByte eventFlags_ )
    :gsmpPortManagementMessage()
{
    _result = result_;
    _transactionIdentifier = transactionIdentifier_;
    _port = port_;
    _portSessionNumber = portSessionNumber_;
    _eventFlags = eventFlags_;
    _function = gsmpPortManagementMessage::RESET_EVENT_FLAGS;
    return;
}

//
// Function: gsmpResetEventFlagsMessage
//
// Description:
//     Copy constructor
//

gsmpResetEventFlagsMessage :: gsmpResetEventFlagsMessage(
    const gsmpResetEventFlagsMessage &other_)
    :gsmpPortManagementMessage(other_)
{
    return;
}

//
// Function: gsmpResetEventFlagsMessage
//
// Description:
//     Destructor
//

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

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

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

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

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