//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / testing/testadapter/sscop
//
//File: sscoptest.cpp
//
//Version: $Revision: 1.8 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/07/22 11:47:34 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications Software and Multimedia
//
//Author:
//      Timo Kokkonen
//
//Description:
//
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History:
//
#include <typeinfo>
#include <OB/CORBA.h>
#include <OB/Util.h>
#include "pf/exception.h"
#include "pf/bytes.h"
#include "sscoppducoder.h"
#include <stdlib.h>
#include <string>
#include "pf/frame.h"
#include "pf/bitstring.h"
#include "pf/debug.h"
#include "testing/testadapter/adapter/msg.h"

void printUsage(string argv0_);
pfFrame decode_encode(pfFrame frame_);

main(int argc, char* argv[])
{
    debugOutputCout();

    if (argc == 2)
    {
        pfFrame frame;

        if (argv[1][0] == 'a')
        {
            // N_S 3 octet.
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B1011_1000); // B8
            // PAD 2 octet.
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0000_0000); // 00
            // Information 6 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B1100_1100); // CC
            frame.putFirst(B1000_1000); // 88
            frame.putFirst(B0010_0010); // 22
            frame.putFirst(B0001_0001); // 11

            debugFrame("SD-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded SD-pdu", newFrame);
        }
        else if (argv[1][0] == 'b')
        {
            // RESERVED3 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED2(4 bytes) + type(4 bytes).
            frame.putFirst(B1010_0100); // A4
            // RESERVED1 4 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7

            debugFrame("ENDAK-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded ENDAK-pdu", newFrame);
        }
        else if (argv[1][0] == 'c')
        {
            // N_MR 3 octet.
            frame.putFirst(B1010_0101); // A5
            frame.putFirst(B0001_0010); // 12
            frame.putFirst(B0100_1111); // 3F
            // PDU-header 1 octet. Rsvd(4 bytes) + type(4 bytes).
            frame.putFirst(B1101_1001); // D9
            // N_SQ 1 octet.
            frame.putFirst(B1111_0000); // F0
            // RESERVED 3 octet
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7

            debugFrame("ER-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded ER-pdu", newFrame);
        }
        else if (argv[1][0] == 'd')
        {
            // N_MR 3 octet.
            frame.putFirst(B1010_0101); // A5
            frame.putFirst(B0001_0010); // 12
            frame.putFirst(B0100_1111); // 3F
            // PDU-header 1 octet. Rsvd(4 bytes) + type(4 bytes).
            frame.putFirst(B1101_1111); // DF
            // RESERVED 4 octet
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7

            debugFrame("ERAK-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded ERAK-pdu", newFrame);
        }
        else if (argv[1][0] == 'e')
        {
            // N_MR 3 octet.
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B0111_0001); // 71
            // N_SQ 1 octet
            frame.putFirst(B1101_1111); // DF
            // RESERVED 3 octet
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            // PAD 1 octet.
            frame.putFirst(B0000_0000); // 00
            // UU 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21
            
            // IVPDU-length
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21

            debugFrame("BGN-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded BGN-pdu", newFrame);
        }
        else if (argv[1][0] == 'f')
        {
            // N_MR 3 octet.
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B1111_0010); // F2
            // RESERVED 4 octet
            frame.putFirst(B1101_1111); // DF
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            // PAD 3 octet.
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0001_0100); // 14
            frame.putFirst(B1001_0010); // 92
            // UU 5 octet.
            frame.putFirst(B1101_1110); // DE
            frame.putFirst(B1110_1101); // ED
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21

            debugFrame("BGAK-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded BGAK-pdu", newFrame);
        }
        else if (argv[1][0] == 'g')
        {
            // RESERVED2 3 octet.
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RR(1 bytes) + S(1 bytes)
            // + type(4 bytes).
            frame.putFirst(B0001_0011); // 13
            // RESERVED 4 octet
            frame.putFirst(B1101_1111); // DF
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            // PAD 0 octet.
            // UU 8 octet.
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0001_0100); // 14
            frame.putFirst(B1001_0010); // 92
            frame.putFirst(B1101_1110); // DE
            frame.putFirst(B1110_1101); // ED
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21

            debugFrame("END-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded END-pdu", newFrame);
        }
        else if (argv[1][0] == 'h')
        {
            // N_MR 3 octet.
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B0111_0101); // 75
            // N_SQ 1 octet
            frame.putFirst(B1101_1111); // DF
            // RESERVED 3 octet
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            // PAD 1 octet.
            frame.putFirst(B0000_0000); // 00
            // UU 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21

            debugFrame("RS-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded RS-pdu", newFrame);
        }
        else if (argv[1][0] == 'i')
        {
            // N_MR 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED2(4 bytes) + type(4 bytes).
            frame.putFirst(B1010_0110); // A6
            // RESERVED1 4 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7

            debugFrame("RSAK-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded RSAK-pdu", newFrame);
        }
        else if (argv[1][0] == 'j')
        {
            // RESERVED2 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. PL(2 bytes) +  RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B0110_0111); // 67
            // RESERVED1 4 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7
            // PAD 1 octet.
            frame.putFirst(B0000_0000); // 00
            // UU 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21

            debugFrame("BGREJ-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded BGREJ-pdu", newFrame);
        }
        else if (argv[1][0] == 'k')
        {
            // N_S 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED2(4 bytes) + type(4 bytes).
            frame.putFirst(B0110_1010); // 6A
            // N_PS 3 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            // RESERVED1 1 octet.
            frame.putFirst(B1110_0111); // E7

            debugFrame("POLL-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded POLL-pdu", newFrame);
        }
        else if (argv[1][0] == 'l')
        {
            // N_R 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED(4 bytes) + type(4 bytes).
            frame.putFirst(B0110_1011); // 6B
            // N_MR 3 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            // RSVD2 1 octet.
            frame.putFirst(B1110_0111); // E7
            // N_PS 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21
            // RSVD1 1 octet.
            frame.putFirst(B0000_0000); // 00
            // LE2 3 octet.
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B0010_0001); // 21
            // PAD2 1 octet.
            frame.putFirst(B0100_0001); // 41
            // LE1 3 octet.
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B0010_0001); // 21
            // PAD1 1 octet.
            frame.putFirst(B0100_0001); // 41

            debugFrame("STAT-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded STAT-pdu", newFrame);
        }
        else if (argv[1][0] == 'm')
        {
            // N_R 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED(4 bytes) + type(4 bytes).
            frame.putFirst(B0110_1100); // 6C
            // N_MR 3 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            // RESERVED1 1 octet.
            frame.putFirst(B1110_0111); // E7
            // LE2 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21
            // PAD2 1 octet.
            frame.putFirst(B0000_0000); // 00
            // LE1 3 octet.
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B0010_0001); // 21
            // PAD1 1 octet.
            frame.putFirst(B0100_0001); // 41
 
            debugFrame("USTAT-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded USTAT-pdu", newFrame);
        }
        else if (argv[1][0] == 'n')
        {
            // RESERVED 3 octet.
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B1011_1101); // BD
            // PAD 2 octet.
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0000_0000); // 00
            // Information 6 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B1100_1100); // CC
            frame.putFirst(B1000_1000); // 88
            frame.putFirst(B0010_0010); // 22
            frame.putFirst(B0001_0001); // 11

            debugFrame("UD-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded UD-pdu", newFrame);
        }
        else if (argv[1][0] == 'o')
        {
            // RESERVED 3 octet.
            frame.putFirst(B0000_1111); // 0F
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B0000_1111); // 0F
            // PDU-header 1 octet. PL(2 bytes) + RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B1011_1110); // BE
            // PAD 2 octet.
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1000_1000); // 88
            // Information 6 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1100_1100); // CC
            frame.putFirst(B0010_0010); // 22
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0001_0001); // 11

            debugFrame("MD-pdu created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded MD-pdu", newFrame);
        }
        else if (argv[1][0] == 'p')
        {
            frame.putFirst(B1010_0101); // A5
            frame.putFirst(B0001_0010); // 12
            frame.putFirst(B0100_1111); // 3F
            // type 0000
            frame.putFirst(B1111_0000); // F0
            frame.putFirst(B1101_1111); // DF
            frame.putFirst(B1011_0000); // B0
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7

            debugFrame("unknown-pdu created (type 0000)", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encode unknown-pdu (type 0000)", newFrame);

        }
        else if (argv[1][0] == 'q')
        {
            frame.putFirst(B1010_0101); // A5
            frame.putFirst(B0001_0010); // 12
            frame.putFirst(B0100_1111); // 3F

            debugFrame("unknown-pdu created (too short)", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encode unknown-pdu (too short)", newFrame);
        }
        else if (argv[1][0] == 'r')
        {
            // RESERVED2 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. PL(2 bytes) +  RSVD(2 bytes) + type(4 bytes).
            frame.putFirst(B0010_0111); // 27
            // RESERVED1 4 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            frame.putFirst(B1110_0111); // E7
            // PAD 0 octet.
            // UU 0 octet.

            debugFrame("BGREJ-pdu (UULength = 0) created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded BGREJ-pdu (UULength = 0)", newFrame);
        }
        else if (argv[1][0] == 's')
        {
            // N_R 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED(4 bytes) + type(4 bytes).
            frame.putFirst(B0110_1011); // 6B
            // N_MR 3 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            // RSVD2 1 octet.
            frame.putFirst(B1110_0111); // E7
            // N_PS 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21
            // RSVD1 1 octet.
            frame.putFirst(B0000_0000); // 00
            // LE1 0 octet.
            // PAD1 0 octet.

            debugFrame("STAT-pdu (listLength = 0) created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded STAT-pdu (listLength = 0)", newFrame);
        }
        else if (argv[1][0] == 't')
        {
            // N_R 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED(4 bytes) + type(4 bytes).
            frame.putFirst(B0110_1011); // 6B
            // N_MR 3 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            // RSVD2 1 octet.
            frame.putFirst(B1110_0111); // E7
            // N_PS 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21
            // RSVD1 1 octet.
            frame.putFirst(B0000_0000); // 00
            // LE1 3 octet.
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B0010_0001); // 21
            // PAD1 1 octet.
            frame.putFirst(B0100_0001); // 41
            // Extra octet
            frame.putFirst(B0101_0101); // 55

            debugFrame("STAT-pdu (listLength = 5) created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded STAT-pdu (listLength = 5)", newFrame);
        }
        else if (argv[1][0] == 'u')
        {
            // N_R 3 octet.
            frame.putFirst(B1111_1111); // FF
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B1111_1111); // FF
            // PDU-header 1 octet. RESERVED(4 bytes) + type(4 bytes).
            frame.putFirst(B0110_1011); // 6B
            // N_MR 3 octet.
            frame.putFirst(B1100_0011); // C3
            frame.putFirst(B0000_0000); // 00
            frame.putFirst(B0011_1100); // 3C
            // RSVD2 1 octet.
            frame.putFirst(B1110_0111); // E7
            // N_PS 3 octet.
            frame.putFirst(B1111_1100); // FC
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B0010_0001); // 21
            // RSVD1 1 octet.
            frame.putFirst(B0000_0000); // 00
            // LE1 2 octet.
            frame.putFirst(B1000_0000); // 80
            frame.putFirst(B1111_1100); // FC
            // PAD1 0 octet.

            debugFrame("STAT-pdu (listLength = 2) created", frame);

            pfFrame newFrame = decode_encode(frame);
    
            debugFrame("Encoded STAT-pdu (listLength = 2)", newFrame);
        }
        else
        {
            printUsage(argv[0]);
        }
    }
    else 
    {
        printUsage(argv[0]);
    }
}

void printUsage(string argv0_)
{
    string usage = "Usage: " + argv0_ + " [flag]";

    debugUser(usage);
    debugUser("a <-> SD-pdu");
    debugUser("b <-> ENDAK-pdu");
    debugUser("c <-> ER-pdu");
    debugUser("d <-> ERAK-pdu");
    debugUser("e <-> BGN-pdu");
    debugUser("f <-> BGAK-pdu");
    debugUser("g <-> END-pdu");
    debugUser("h <-> RS-pdu");
    debugUser("i <-> RSAK-pdu");
    debugUser("j <-> BGREJ-pdu");
    debugUser("k <-> POLL-pdu");
    debugUser("l <-> STAT-pdu");
    debugUser("m <-> USTAT-pdu");
    debugUser("n <-> UD-pdu");
    debugUser("o <-> MD-pdu");
    debugUser("p <-> unknown-pdu (type 0000)");
    debugUser("q <-> unknown-pdu (too short)");
    debugUser("r <-> BGREJ-pdu (UULength = 0)");
    debugUser("s <-> STAT-pdu (listLength = 0)");
    debugUser("t <-> STAT-pdu (listLength = 5)");
    debugUser("u <-> STAT-pdu (listLength = 2)");
    return;
}

pfFrame decode_encode(pfFrame frame_)
{
    sscopPDUcoder *testcoder = new sscopPDUcoder;

    otMessage::SerializedMessage testMessage = testcoder->decode(frame_);

    debugUser("Printing created otMessage::SerializedMessage...");
    for (pfUlong i = 0; i < testMessage.length(); ++i)
    {
        otMessage::ElementKind kind = testMessage[i].kind;
        string id = testMessage[i].identifier.in();
        string value = testMessage[i].value.in();
        pfUlong number = testMessage[i].number;
        debugPfUlong("kind", kind);
        debugString("id", id);
        if (kind == otMessage::Integer ||
            kind == otMessage::Boolean)
        {
            debugPfUlong("number", number);
        }
        else
        {
            debugString("value", value);
        }
    }

    pfFrame frame2 = testcoder->encode(testMessage);

    return frame2;
}
