//Editor-Info: -*- C++ -*-
//
//Subject: TOVE project / SSCOP protocol
//
//File: sscoppdu.h
//
//Version: $Revision: 1.10 $
//
//State: $State: Exp $
//
//Date: $Date: 1998/11/27 12:29:57 $
//
//Organisation:
//      Helsinki University of Technology
//      Laboratory of Telecommunications and Multimedia
//
//Author:
//      Juhana Räsänen
//
//Description:
//      Classes for the SSCOP PDUs
//
//Copyright:
//      Copyright 1999 Helsinki University of Technology
//      ALL RIGHTS RESERVED BETWEEN JANUARY 1996 AND JUNE 1999.
//
//Licence:
//
//
//History: 


#ifndef __SSCOPPDU_H__
#define __SSCOPPDU_H__

#include "sscop.h"
#include "pf/transp.h"
#include "pf/frame.h"
#include "pf/types.h"


//
// Class: sscopPDUmessenger
//
// Description:
//     Base class for all SSCOP PDU messengers. Has PDU parameters that
//     are used by more than one PDU and some methods to help decoding
//     of PDUs. Some PDUs may define their own parameters not common to
//     other PDUs.
//

class sscopPDUmessenger : public pfMsgTransporter
{
    public:
        sscopPDUmessenger(void);
        sscopPDUmessenger(const sscopPDUmessenger &other_);
        virtual ~sscopPDUmessenger(void);
        static sscopPDUmessenger *create(const pfFrame &frame_,
                                         pfUlong maxSDUsize_,
                                         pfUlong maxUUsize_);
        const sscopPDUmessenger &operator=(const sscopPDUmessenger &other_);

// Get methods for parameters that are shared between more than one PDU
        pfFrame &getInformation(void);
        pfFrame &getSSCOP_UU(void);
        pfUlong getN_S(void) const;
        pfUlong getN_R(void) const;
        pfUlong getN_PS(void) const;
        pfUlong getN_SQ(void) const;
        pfUlong getN_MR(void) const;
        pfUlong getErrorCode(void) const;

    protected:
        pfByte readPadLength(pfByte typeOctet_) const;
        void removeReserved(pfFrame &frame_, pfUlong n_) const;

        static pfUlong padPDU(pfFrame &frame_);
        static void appendReserved(pfFrame &frame_, int n_);
        static void appendTypeOctet(pfFrame &frame_,
                                    sscopPDU pdu_,
                                    int padLength_ = 0);
 
// PDU parameters are protected members so that the decode methods of
// the actual PDU classes can use them directly without get/set methods
        pfFrame _frame;
        pfUlong _N_S;
        pfUlong _N_R;
        pfUlong _N_PS;
        pfUlong _N_SQ;
        pfUlong _N_MR;

    private:
        virtual pfUlong decode(void) = 0;
        pfUlong _errorCode;
};


//
// Classes: Actual SSCOP PDU messenger classes
//
// Description:
//     SSCOP PDU messengers. Most of the functionality is implemented
//     in the base class, only apply, decode and some fields that are
//     not used by other PDUs are implemented in these classes.
//

class sscopBGN_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopBGN_PDU(void);
        virtual ~sscopBGN_PDU(void);

        static void encode(pfFrame &sscop_uu_, pfUlong n_sq_, pfUlong n_mr_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopBGAK_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopBGAK_PDU(void);
        virtual ~sscopBGAK_PDU(void);

        static void encode(pfFrame &sscop_uu_, pfUlong n_mr_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopBGREJ_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopBGREJ_PDU(void);
        virtual ~sscopBGREJ_PDU(void);

        static void encode(pfFrame &sscop_uu_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopEND_PDU : public sscopPDUmessenger
{
    public:
        static void encode(pfFrame &sscop_uu_, pfUlong source_);
        sscopEND_PDU(void);
        sscopEND_PDU(const sscopEND_PDU &other_);
        virtual ~sscopEND_PDU(void);
        const sscopEND_PDU &operator=(const sscopEND_PDU &other_);

        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);
        pfUlong getSource(void) const;

    private:
        virtual pfUlong decode(void);
        pfUlong _source;
};


class sscopENDAK_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopENDAK_PDU(void);
        virtual ~sscopENDAK_PDU(void);

        static void encode(pfFrame &frame_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopRS_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopRS_PDU(void);
        virtual ~sscopRS_PDU(void);

        static void encode(pfFrame &sscop_uu_, pfUlong n_sq_, pfUlong n_mr_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopRSAK_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopRSAK_PDU(void);
        virtual ~sscopRSAK_PDU(void);

        static void encode(pfFrame &frame_, pfUlong n_mr_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopER_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopER_PDU(void);
        virtual ~sscopER_PDU(void);

        static void encode(pfFrame &frame_, pfUlong n_sq_, pfUlong n_mr_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopERAK_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopERAK_PDU(void);
        virtual ~sscopERAK_PDU(void);

        static void encode(pfFrame &frame_, pfUlong n_mr_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopSD_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopSD_PDU(void);
        virtual ~sscopSD_PDU(void);

        static void encode(pfFrame &data_, pfUlong n_s_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);
        virtual pfUlong getSequenceNumber(void) const;
        void setSequenceNumber(pfUlong sequenceNumber_);
        void setN_PS(pfUlong pollSequenceNumber_);
        void setInformation(const pfFrame &frame_);

    private:
        virtual pfUlong decode(void);
};


class sscopPOLL_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopPOLL_PDU(void);
        virtual ~sscopPOLL_PDU(void);

        static void encode(pfFrame &frame_, pfUlong n_ps_, pfUlong n_s_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopSTAT_PDU : public sscopPDUmessenger
{
    public:
        static void encode(pfFrame &list_,
                           pfUlong n_ps_,
                           pfUlong n_mr_,
                           pfUlong n_r_);
        sscopSTAT_PDU(void);
        sscopSTAT_PDU(const sscopSTAT_PDU &other_);
        virtual ~sscopSTAT_PDU(void);
        const sscopSTAT_PDU &operator=(const sscopSTAT_PDU &other_);

        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);
        pfUlong getNItems(void) const;
        pfUlong getNextListElement(void);

    private:
        virtual pfUlong decode(void);
        pfUlong _nItems;
};


class sscopUSTAT_PDU : public sscopPDUmessenger
{
    public:
        static void encode(pfFrame &frame_,
                           pfUlong listElement1_,
                           pfUlong listElement2_,
                           pfUlong n_mr_,
                           pfUlong n_r_);
        sscopUSTAT_PDU(void);
        sscopUSTAT_PDU(const sscopUSTAT_PDU &other_);
        virtual ~sscopUSTAT_PDU(void);
        const sscopUSTAT_PDU &operator=(const sscopUSTAT_PDU &other_);

        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);
        pfUlong getListElement1(void) const;
        pfUlong getListElement2(void) const;

    private:
        virtual pfUlong decode(void);
        pfUlong _listElement1;
        pfUlong _listElement2;
};


class sscopUD_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopUD_PDU(void);
        virtual ~sscopUD_PDU(void);

        static void encode(pfFrame &data_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopMD_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopMD_PDU(void);
        virtual ~sscopMD_PDU(void);

        static void encode(pfFrame &data_);
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


class sscopINVALID_PDU : public sscopPDUmessenger
{
    public:
        // MODIFIED: jturunen
        sscopINVALID_PDU(void);
        virtual ~sscopINVALID_PDU(void);
        
        virtual void atProtocol(pfProtocol *protocol_, pfState *state_);

    private:
        virtual pfUlong decode(void);
};


#endif // __SSCOPPDU_H__



