//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project
//
//File: testmessenger.cpp
//
//Version: $Revision: 1.1 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/06/05 08:18:06 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Harri Sunila
//
//Description:
//
//
//Copyright:
//
//
//Licence:
//
//
//History: 

#include "testmessenger.h"

testMessenger :: testMessenger(void)
    : pfMessenger(),
      _frame()
{
    return;
}

testMessenger :: testMessenger(const testMessenger &other_)
    : pfMessenger(other_),
      _frame(other_._frame)
{
    return;
}

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

testMessenger *testMessenger :: create(pfFrame &frame_)
    throw (pfMemoryAllocationException, pfInvalidTypeException)
{
    testMessenger *messenger;
    pfByte type = frame_.read(1); // Message type location

    switch (type)
    {
        case TEST_STORAGEMESSENGER:
            messenger = new testStorageMessenger;
            break;
        case TEST_REFERENCEMESSENGER:
            messenger = new testReferenceMessenger;
            break;
        default:
            throw pfInvalidTypeException(PF_EX_INFO);
            break;
    }

    if (messenger != 0)
    {
        try
        {
            messenger->decode(frame_);
        }
        catch (pfMethodFailed &exception)
        {
            delete messenger;
            messenger = 0;
            exception.printInfo();
        }
    }
    else
    {
        throw pfInvalidTypeException(PF_EX_INFO);
    }
    return messenger;
}

pfFrame &testMessenger :: returnFrame(void)
{
    return _frame;
}

testStorageMessenger :: testStorageMessenger(void)
    : testMessenger()
{
    defineFrame("Frame");
    defineInteger("Version");
    setInteger("Version", 1);
    defineInteger("Message Type");
    setInteger("Message Type", TEST_STORAGEMESSENGER);
    defineInteger("Result");
    setInteger("Result", 0);
    defineInteger("Code");
    setInteger("Code", 0);
    defineInteger("Transaction Identifier");
    setInteger("Transaction Identifier", 0);
    defineInteger("Port Session Number");
    setInteger("Port Session Number", 0);
    defineInteger("Input Port");
    setInteger("Input Port", 0);
    defineInteger("Input VPI");
    setInteger("Input VPI", 0);
    defineInteger("Input VCI");
    setInteger("Input VCI", 0);
    defineInteger("Output Port");
    setInteger("Output Port" ,0);
    defineInteger("Output VPI");
    setInteger("Output VPI", 0);
    defineInteger("Output VCI");
    setInteger("Output VCI", 0);
    defineInteger("Number of Branches");
    setInteger("Number of Branches", 0);
    defineInteger("Priority");
    setInteger("Priority", 0);
    return;
}

testStorageMessenger :: testStorageMessenger(pfByte result_,
                                             pfByte code_,
                                             pfUlong transactionIdentifier_,
                                             pfUlong portSessionNumber_,
                                             pfUlong inputPort_,
                                             pfUlong inputVPI_,
                                             pfUlong inputVCI_,
                                             pfUlong outputPort_,
                                             pfUlong outputVPI_,
                                             pfUlong outputVCI_,
                                             pfUlong numberOfBranches_,
                                             pfByte priority_)
    : testMessenger()
{
    defineFrame("Frame");
    defineInteger("Version");
    setInteger("Version", 1);
    defineInteger("Message Type");
    setInteger("Message Type", TEST_STORAGEMESSENGER);
    defineInteger("Result");
    setInteger("Result", result_);
    defineInteger("Code");
    setInteger("Code", code_);
    defineInteger("Transaction Identifier");
    setInteger("Transaction Identifier", transactionIdentifier_);
    defineInteger("Port Session Number");
    setInteger("Port Session Number", portSessionNumber_);
    defineInteger("Input Port");
    setInteger("Input Port", inputPort_);
    defineInteger("Input VPI");
    setInteger("Input VPI", inputVPI_);
    defineInteger("Input VCI");
    setInteger("Input VCI", inputVCI_);
    defineInteger("Output Port");
    setInteger("Output Port" ,outputPort_);
    defineInteger("Output VPI");
    setInteger("Output VPI", outputVPI_);
    defineInteger("Output VCI");
    setInteger("Output VCI", outputVCI_);
    defineInteger("Number of Branches");
    setInteger("Number of Branches", numberOfBranches_);
    defineInteger("Priority");
    setInteger("Priority", priority_);
    return;
}

testStorageMessenger :: testStorageMessenger(
    const testStorageMessenger &other_)
    : testMessenger(other_)
{
    return;
}

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

void testStorageMessenger :: decode(pfFrame &frame_) throw (pfMethodFailed)
{
    setFrame("Frame", frame_);
    pfByte version = frame_.getFirst();
    pfByte type = frame_.getFirst();
    pfByte result = frame_.getFirst();
    pfByte code = frame_.getFirst();
    pfUlong transactionIdentifier = frame_.getFirst32bit();
    pfUlong portSessionNumber = frame_.getFirst32bit();
    pfUlong inputPort = frame_.getFirst32bit();
    pfUlong inputVPI = (frame_.getFirst16bit() & 0x0FFF);
    pfUlong inputVCI = frame_.getFirst16bit();
    pfUlong outputPort = frame_.getFirst32bit();
    pfUlong outputVPI = (frame_.getFirst16bit() & 0x0FFF);
    pfUlong outputVCI = frame_.getFirst16bit();
    pfUlong numberOfBranches = frame_.getFirst16bit();
    frame_.getFirst();
    pfByte priority = frame_.getFirst();
    if (frame_.length() != 0)
    {
        throw pfMethodFailed("Frame not empty!", PF_EX_INFO);
    }
    try
    {
        setInteger("Version", version);
        setInteger("Message Type", type);
        setInteger("Result", result);
        setInteger("Code", code);
        setInteger("Transaction Identifier", transactionIdentifier);
        setInteger("Port Session Number", portSessionNumber);
        setInteger("Input Port", inputPort);
        setInteger("Input VPI", inputVPI);
        setInteger("Input VCI", inputVCI);
        setInteger("Output Port", outputPort);
        setInteger("Output VPI", outputVPI);
        setInteger("Output VCI", outputVCI);
        setInteger("Number of Branches", numberOfBranches);
        setInteger("Priority", priority);
    }
    catch (pfException &exception)
    {
        exception.printInfo();
        throw pfMethodFailed("Exception in setInteger()", PF_EX_INFO);
    }
    return;
}

void testStorageMessenger :: encode(void)
{
    pfFrame frame;
    try
    {
        frame.putLast((pfByte) getInteger("Version"));
        frame.putLast((pfByte) getInteger("Message Type"));
        frame.putLast((pfByte) getInteger("Result"));
        frame.putLast((pfByte) getInteger("Code"));
        frame.putLast32bit(getInteger("Transaction Identifier"));
        frame.putLast32bit(getInteger("Port Session Number"));
        frame.putLast32bit(getInteger("Input Port"));
        frame.putLast16bit((getInteger("Input VPI") & 0x0FFF));
        frame.putLast16bit(getInteger("Input VCI"));
        frame.putLast32bit(getInteger("Output Port"));
        frame.putLast16bit((getInteger("Output VPI") & 0x0FFF));
        frame.putLast16bit(getInteger("Output VCI"));
        frame.putLast16bit(getInteger("Number of Branches"));
        frame.putLast(0);
        frame.putLast((pfByte) getInteger("Priority"));
        setFrame("Frame", frame);
    }
    catch (pfException &exception)
    {
        exception.printInfo();
    }
    return;
}


testReferenceMessenger :: testReferenceMessenger(void)
    : testMessenger(),
      _version(1),
      _type(TEST_REFERENCEMESSENGER),
      _result(0),
      _code(0),
      _transactionIdentifier(0),
      _portSessionNumber(0),
      _inputPort(0),
      _inputVPI(0),
      _inputVCI(0),
      _outputPort(0),
      _outputVPI(0),
      _outputVCI(0),
      _numberOfBranches(0),
      _priority(0)
{
    return;
}

testReferenceMessenger :: testReferenceMessenger(
    pfByte result_,
    pfByte code_,
    pfUlong transactionIdentifier_,
    pfUlong portSessionNumber_,
    pfUlong inputPort_,
    pfUlong inputVPI_,
    pfUlong inputVCI_,
    pfUlong outputPort_,
    pfUlong outputVPI_,
    pfUlong outputVCI_,
    pfUlong numberOfBranches_,
    pfByte priority_)
    : testMessenger(),
      _version(1),
      _type(TEST_REFERENCEMESSENGER),
      _result(result_),
      _code(code_),
      _transactionIdentifier(transactionIdentifier_),
      _portSessionNumber(portSessionNumber_),
      _inputPort(inputPort_),
      _inputVPI(inputVPI_),
      _inputVCI(inputVCI_),
      _outputPort(outputPort_),
      _outputVPI(outputVPI_),
      _outputVCI(outputVCI_),
      _numberOfBranches(numberOfBranches_),
      _priority(priority_)
{
    return;
}

testReferenceMessenger :: testReferenceMessenger(
    const testReferenceMessenger &other_)
    : testMessenger(other_),
      _version(other_._version),
      _type(other_._type),
      _result(other_._result),
      _code(other_._code),
      _transactionIdentifier(other_._transactionIdentifier),
      _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;
}

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

void testReferenceMessenger :: decode(pfFrame &frame_) throw (pfMethodFailed)
{
    _frame = frame_;
    _version = frame_.getFirst();
    _type = frame_.getFirst();
    _result = frame_.getFirst();
    _code = frame_.getFirst();
    _transactionIdentifier = frame_.getFirst32bit();
    _portSessionNumber = frame_.getFirst32bit();
    _inputPort = frame_.getFirst32bit();
    _inputVPI = (frame_.getFirst16bit() & 0x0FFF);
    _inputVCI = frame_.getFirst16bit();
    _outputPort = frame_.getFirst32bit();
    _outputVPI = (frame_.getFirst16bit() & 0x0FFF);
    _outputVCI = frame_.getFirst16bit();
    _numberOfBranches = frame_.getFirst16bit();
    frame_.getFirst();
    _priority = frame_.getFirst();

    if (frame_.length() != 0)
    {
        throw pfMethodFailed("Frame not empty!", PF_EX_INFO);
    }
    return;
}

void testReferenceMessenger :: encode(void)
{
    _frame.clear();
    _frame.putLast(_version);
    _frame.putLast(_type);
    _frame.putLast(_result);
    _frame.putLast(_code);
    _frame.putLast32bit(_transactionIdentifier);
    _frame.putLast32bit(_portSessionNumber);
    _frame.putLast32bit(_inputPort);
    _frame.putLast16bit((_inputVPI & 0x0FFF));
    _frame.putLast16bit(_inputVCI);
    _frame.putLast32bit(_outputPort);
    _frame.putLast16bit((_outputVPI & 0x0FFF));
    _frame.putLast16bit(_outputVCI);
    _frame.putLast16bit(_numberOfBranches);
    _frame.putLast(0);
    _frame.putLast(_priority);
    return;
}

pfFrame &testReferenceMessenger :: returnFrame(void)
{
    return _frame;
}
