//  ==========================================================================
//  
//  @(#) $Id: SCCP_Codec.C,v 1.4 2000/10/19 03:21:57 brian Exp $
//  
//  --------------------------------------------------------------------------
//  
//  Copyright (C) 1997-2000  Brian Bidulock <bidulock@dallas.net>
//  
//  All Rights Reserved.
//  
//  This library is free software; you can redistribute it and/or modify it
//  under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation; either version 2.1 of the License, or (at
//  your option) any later version.
//  
//  This library is distributed in the hope that it will be useful, but
//  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
//  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License
//  for more details.
//  
//  You should have received a copy of the GNU Lesser General Public License
//  along with this library; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
//  Last Modified $Date: 2000/10/19 03:21:57 $ by $Author: brian $
// 
//  --------------------------------------------------------------------------
// 
//  $Log: SCCP_Codec.C,v $
//  Revision 1.4  2000/10/19 03:21:57  brian
//  Whoops, messed up when adding headers.
//
//  Revision 1.3  2000/10/13 15:45:51  brian
//  First public release.
//
//  ==========================================================================

static char const ident[] = "$Id: SCCP_Codec.C,v 1.4 2000/10/19 03:21:57 brian Exp $";

#pragma implementation

#include "SCCP_Codec.H"
#include <iostream.h>

Codec_AP::Codec_AP(char* l,char* t) :
    Content(l,t,-1,1,0,(Codec**)&PDU) {
    PDU = new OctetString(l,t,-1);
};

Codec_SCMG::Codec_SCMG(char* l,char* t) :
    Parameter(l,t,-1,4,0,(Codec**)&MTC) {
    MTC = new Set("MTC","SCMG Format Indicator",8,0,
        "SSA",  1,  "Subsystem Allowed",
        "SSP",  2,  "Subsystem Prohibited",
        "SST",  3,  "Subsystem Status Test",
        "SOR",  4,  "Subsystem Out of Service Request",
        "SOG",  5,  "Subsystem Out of Service Grant",
        "SBR",  253,"Subsystem Backup Routing",
        "SNR",  254,"Subsystem Normal Routing",
        "SRT",  255,"Subsystem Routing Status Test",
        NULL);
    ASSN = new Codec_SSN("ASSN","Affected Subsystem No.");
    APC = new Codec_PC("APC","Affected Point Code");
    SMI = new Set("SMI","Subsystem Multi Ind",2,6,
        "ASU",  0,  "Affected subsystem unknown",
        "ASS",  1,  "Affected subsystem is solitary",
        "ASD",  2,  "Affected subsystem is duplicated",
        NULL);

    
};

Codec_UPART::Codec_UPART(char* l,char* t,Codec* ssni,Codec* ssn) :
    ParameterPL(l,t,-1,3,16,(Codec**)&PTR) {
    
    SCMG = new Codec_SCMG("SCMG","SCCP Management");
    ISUP = new Codec_AP("ISUP","ISDN User Part");
    OMAP = new Codec_AP("OMAP","OA&M Application Part");
    MAP  = new Codec_AP("MAP", "Mobile Application Part");
    HLR  = new Codec_AP("HLR", "Home Location Register");
    VLR  = new Codec_AP("VLR", "Visitor Location Register");
    MSC  = new Codec_AP("MSC", "Mobile Switching Center");
    EIR  = new Codec_AP("EIR", "Equipment Identity Register");
    AC   = new Codec_AP("AC",  "Authentication Center");
    OGCMS= new Codec_AP("OGCMS","1 Way Outgoing CMS");
    CMS  = new Codec_AP("CMS", "CMS/CLASS Service");
    BNS  = new Codec_AP("BNS", "LIDB/BNS Database");
    ACCS = new Codec_AP("ACCS","LIDB/ACCS Database");
    INAP = new Codec_AP("INAP","8XX Database");
    TCAP = new Codec_AP("TCAP","Trans Cap Appl Part");
    
    PTR = new Field("PTR","Parameter Pointer",8,0);
    PL  = new Field("PL", "Parameter Length",8,0);
    SSN_B = new Bra("SSN:","SSN Branch",ssn,
            SCMG ,  1, ISUP ,  3, OMAP ,  4, MAP  ,  5, HLR  ,  6,
            VLR  ,  7, MSC  ,  8, EIR  ,  9, AC   , 10, OGCMS,250,
            CMS  ,251, BNS  ,252, ACCS ,253, INAP ,254, TCAP , -1,
        NULL);
    SSNI_B = new Bra("SSNI:","SSNI Branch",ssni,
            SSN_B,  1, TCAP , -1,
        NULL);
};

Codec_DLR::Codec_DLR() :
    Parameter("DLR","Dest Local Reference",8,1,0,(Codec**)&DLR) {
    DLR  = new Field("DLR","Dest Local Reference",8,0);
};

Codec_SLR::Codec_SLR() :
    Parameter("SLR","Source Local Reference",8,1,0,(Codec**)&SLR) {
    SLR  = new Field("SLR","Srce Local Reference",8,0);
};

Codec_PCL::Codec_PCL() :
    Parameter("PCL","Protocol Cls & Options",-1,2,0,(Codec**)&PCL) {
    PCL = new Set("PCL","Protocol Class",4,0,
        "PC0",  0,  "Connectionless protocol class 0",
        "PC1",  1,  "Connectionless protocol class 1",
        "PC2",  2,  "Connection-oriented protocol class 2",
        "PC3",  2,  "Connection-oriented protocol class 3",
        NULL);
    OPT = new Set("OPT","Options",4,0,
        "NSO",  0,  "No special options",
        "RMOE", 8,  "Return message on error",
        NULL);
};

Codec_SEG::Codec_SEG() :
    Parameter("SEG","Segmentation",8,1,0,(Codec**)&SEG) {
    SEG  = new Set("SEG","Segmentation",1,7,
        "NO",   0,  "No more data",
        "YES",  1,  "More data",
        NULL);
};

Codec_PRN::Codec_PRN() :
    Parameter("PRN","Recv Sequence Number",8,2,0,(Codec**)&PR0) {
    PR0 = new Field("PR0","Spare P(R) Bit",0,1);
    PR  = new Field("PR","Recv Sequence Number",7,0);
};

Codec_SEQ::Codec_SEQ() :
    Parameter("SEQ","Sequence/Segmentation",16,4,0,(Codec**)&PS0) {
    PS0 = new Field("PS0","Spare P(S) Bit",0,1);
    PS  = new Field("PS","Send Sequence Number",7,0);
    MDI = new Set("MDI","More Data Indicator",1,0,
        "NO",   0,  "No more data",
        "YES",  1,  "More data",
        NULL);
    PR  = new Field("PR","Recv Sequence Number",7,0);
};

Codec_CREDIT::Codec_CREDIT() :
    Parameter("CREDIT","Credit",8,1,0,(Codec**)&CREDIT) {
    CREDIT = new Field("CREDIT","Credit",8,0);
};

Codec_RELC::Codec_RELC() :
    Parameter("RELC","Release Cause",8,1,0,(Codec**)&RELC) {
    RELC = new Set("RELC","Release Cause",8,0,
        "EUO",  0,  "End user originated",
        "EUC",  1,  "End user busy",
        "EUF",  2,  "End user failure",
        "SCCP", 3,  "SCCP user originated",
        "RPE",  4,  "Remote procedure error",
        "ICD",  5,  "Inconsistent connection data",
        "AF",   6,  "Access failure",
        "AC",   7,  "Access congestion",
        "SSF",  8,  "Subsystem failure",
        "SSC",  9,  "Subsystem congestion",
        "NF",   10, "MTP failure",
        "NC",   11, "Network congestion",
        "XRT",  12, "Expiration of reset timer",
        "XRIT", 13, "Expriation of receive inactivity timer",
        "NOB",  14, "Not obtainable",
        "UNQ",  15, "Unqualified",
        "FAIL", 16, "SCCP failure",
        NULL);
};

Codec_RETC::Codec_RETC() :
    Parameter("RETC","Return Cause",8,1,0,(Codec**)&RETC) {
    RETC = new Set("RETC","Return Cause",8,0,
        "NTA",  0,  "No trans for address of such nature",
        "NTS",  1,  "No trnaslation for specific address",
        "SSC",  2,  "Subsystem congestion",
        "SSF",  3,  "Subsystem failiure",
        "UU",   4,  "Unequipped user",
        "NF",   5,  "MTP failure",
        "NC",   6,  "Network congestion",
        "UNQ",  7,  "Unqualified",
        "MT",   8,  "Error in message transport",
        "LP",   9,  "Error in local processing",
        "DCPA", 10, "Destination cannot perform reassembly",
        "FAIL", 11, "SCCP failure",
        NULL);
};

Codec_RSTC::Codec_RSTC() :
    Parameter("RSTC","Reset Cause",8,1,0,(Codec**)&RSTC) {
    RSTC = new Set("RSTC", "Reset Cause",8,0,
        "EUO",  0,  "End user originated",
        "SCCP", 1,  "SCCP user originated",
        "MOOS", 2,  "Msg out of order-incorrect P(S)",
        "MOOR", 3,  "Msg out of order-incorrect P(R)",
        "RPEW", 4,  "Remote proc error-msg out of window",
        "RPES", 5,  "Remote proc error-incorrect P(S)",
        "RPEG", 6,  "Remote proc error-general",
        "REUO", 7,  "Remote end user operational",
        "NO",   8,  "Network operational",
        "AO",   9,  "Access operational",
        "NC",   10, "Network congestion",
        "NOB",  11, "Not obtainable",
        "UNQ",  12, "Unqualified",
        NULL);
};

Codec_ERRC::Codec_ERRC() :
    Parameter("ERRC","Error Cause",8,1,0,(Codec**)&ERRC) {
    ERRC = new Set("ERRC", "Error Cause",8,0,
        "LRN1", 0,  "Unassigned destination LRN",
        "LRN2", 1,  "Inconsistent source LRN",
        "PCM",  2,  "Point code mismatch",
        "SCM",  3,  "Service class mismatch",
        "UNQ",  4,  "Unqualified",
        NULL);
};

Codec_REFC::Codec_REFC() :
    Parameter("REFC","Refusal Cause",8,1,0,(Codec**)&REFC) {
    REFC = new Set("REFC","Refusal Cause",8,0,
        "EUO",  0,  "End user originated",
        "EUC",  1,  "End user congestion",
        "EUF",  2,  "End user failure",
        "SCCP", 3,  "SCCP user originated",
        "DAU",  4,  "Destination address unknown",
        "DAI",  5,  "Destination address inaccessible",
        "QOS",  6,  "QOS not available/non-transient",
        "QOST", 7,  "QOS not available/transient",
        "AF",   8,  "Access failure",
        "AC",   9,  "Access congestion",
        "SSF",  10, "Subsystem failure",
        "SSC",  11, "Subsystem congestion",
        "XCET", 12, "Exp. of connection estab timer",
        "IUD",  13, "Incompatible user data",
        "NOB",  14, "Not obtainable",
        "UNQ",  15, "Unqualified",
        NULL);
};

Codec_DATA::Codec_DATA() :
    Parameter("DATA","Data",-1,1,0,(Codec**)&DATA) {
    DATA = new OctetString("DATA","Data",-1);
};

Codec_SEGM::Codec_SEGM() :
    Parameter("SEGM","Segmentation",32,4,0,(Codec**)&RSEG) {
    RSEG = new Field("RSEG","Remaining Segments",4,2);
    C    = new Set("C","In Sequence Delivery",1,0,
        "NO",   0,  "Not in sequence delivery",
        "YES",  1,  "In sequence delivery",
        NULL);
    F    = new Set("F","First Segment Ind",1,0,
        "FIRST",  0,  "First segment",
        "OTHER",  1,  "Segment other than first",
        NULL);
    LREF = new Field("LREF","Local Reference",24,0);
};

Codec_SCCPHOP::Codec_SCCPHOP() :
    Parameter("SCCPHOP","SCCP Hop Counter",8,1,0,(Codec**)&SCCPHOP) {
    SCCPHOP = new Field("SCCPHOP","SCCP Hop Counter",8,0);
};

// ************************************************
// ****
// **** Mandatory variable parameters
// ****
// ************************************************

Codec_CDPA_M::Codec_CDPA_M() :
    ParameterPL("CDPA","Called Party Address",-1,3,0,(Codec**)&PTR) {
    PTR  = new Field("PTR","Parameter Pointer",8,0);
    PL   = new Field("PL","Parameter Length",8,0);
    CDPA = new Codec_CPA("CDPA","Called Party Address");
};

Codec_CGPA_M::Codec_CGPA_M() :
    ParameterPL("CGPA","Calling Party Address",-1,3,0,(Codec**)&PTR) {
    PTR  = new Field("PTR","Parameter Pointer",8,0);
    PL   = new Field("PL","Parameter Length",8,0);
    CGPA = new Codec_CPA("CGPA","Calling Party Address");
};

Codec_DATA_M::Codec_DATA_M() :
    ParameterPL("DATA","Data",-1,3,0,(Codec**)&PTR) {
    PTR  = new Field("PTR","Parameter Pointer",8,0);
    PL   = new Field("PL","Parameter Length",8,0);
    DATA = new Codec_DATA();
};

// ************************************************
// ****
// **** Optional Parameter List
// ****
// ************************************************

Codec_SOPARM::Codec_SOPARM(char* l,char* t,Codec** a) :
    ParameterNL(l,t,8,3,0,(Codec**)&PNAM) {
    PNAM   = (Field*)a[0];
    PL     = (Field*)a[1];
    PNAM_B = (Bra*  )a[2];
};

Codec_SOPARM::Codec_SOPARM(const Codec_SOPARM& original) :
    ParameterNL((ParameterNL&)original) {
    PNAM   = new Field(*original.PNAM  );
    PL     = new Field(*original.PL    );
    PNAM_B = new Bra  (*original.PNAM_B);
    PNAM_B->branch = PNAM;
    content = (Codec**)&PNAM;
};

Codec_SOPARM*
Codec_SOPARM::copy() {
    return new Codec_SOPARM(*this);
};

Codec_SOPARMS::Codec_SOPARMS(char* l,char* t) :
    ParameterP(l,t,8,2,18,(Codec**)&PTR) {

    PTR     = new Field("PTR","Parameter Pointer",8,0);

    DLR     = new Codec_DLR    ();
    SLR     = new Codec_SLR    ();
    CDPA    = new Codec_CPA    ("CDPA","Called Party Address");
    CGPA    = new Codec_CPA    ("CGPA","Calling Party Address");
    PCL     = new Codec_PCL    ();
    SEG     = new Codec_SEG    ();
    PRN     = new Codec_PRN    ();
    SEQ     = new Codec_SEQ    ();
    CREDIT  = new Codec_CREDIT ();
    RELC    = new Codec_RELC   ();
    RETC    = new Codec_RETC   ();
    RSTC    = new Codec_RSTC   ();
    ERRC    = new Codec_ERRC   ();
    REFC    = new Codec_REFC   ();
    DATA    = new Codec_DATA   ();
    SEGM    = new Codec_SEGM   ();
    SCCPHOP = new Codec_SCCPHOP();
    UREC    = new Codec_UREC   ("UREC",   "Unrecognized Parameter");

    PNAM   = new Field("PNAM","Parameter Name",8,0);
    PL     = new Field("PL","Parameter Length",8,0);
    PNAM_B = new Bra("PNAM:","PNAM Branch",(Codec*)PNAM,
            DLR    ,  1, SLR    ,  2, CDPA   ,  3, CGPA   ,  4,
            PCL    ,  5, SEG    ,  6, PRN    ,  7, SEQ    ,  8,
            CREDIT ,  9, RELC   , 10, RETC   , 11, RSTC   , 12,
            ERRC   , 13, REFC   , 14, DATA   , 15, SEGM   , 16,
            SCCPHOP, 17, SCCPHOP,249,
            UREC   , -1,
        NULL);

    OPARM = new Codec_SOPARM("OPARM","Optional Parameter",(Codec**)&PNAM);
};

// ************************************************
// ****
// **** SCCP Messages
// ****
// ************************************************

Codec_SCCP::Codec_SCCP() :
    Header("SCCP","Signalling Connection Control Part Msg",-1,2,18+17,(Codec**)&MT) {
    
    // ************************************************
    // ****
    // **** Mandatory Parameters
    // ****
    // ************************************************

    DLR     = new Codec_DLR    ();
    SLR     = new Codec_SLR    ();
    CDPA    = new Codec_CDPA_M ();
    CGPA    = new Codec_CGPA_M ();
    PCL     = new Codec_PCL    ();
    SEG     = new Codec_SEG    ();
    PRN     = new Codec_PRN    ();
    SEQ     = new Codec_SEQ    ();
    CREDIT  = new Codec_CREDIT ();
    RELC    = new Codec_RELC   ();
    RETC    = new Codec_RETC   ();
    RSTC    = new Codec_RSTC   ();
    ERRC    = new Codec_ERRC   ();
    REFC    = new Codec_REFC   ();
    DATA    = new Codec_DATA_M ();
    SCCPHOP = new Codec_SCCPHOP();
    UPART   = new Codec_UPART  ("UPART",  "User Part PDU",
                                    CDPA->CDPA->SSNI,CDPA->CDPA->SSN);
    
    OPARMS = new Codec_SOPARMS("OPARMS","Optional Parameters");
    
    // ************************************************
    // ****
    // **** Messages
    // ****
    // ************************************************
    
    CR   = new ParameterG("CR",   "Connection Request",    SLR,PCL,CDPA,OPARMS,NULL);
    CC   = new ParameterG("CC",   "Connection Confirm",    DLR,SLR,PCL,OPARMS,NULL);
    CREF = new ParameterG("CREF", "Connection Refused",    DLR,REFC,OPARMS,NULL);
    RLSD = new ParameterG("RLSD", "Released",              DLR,SLR,RELC,OPARMS,NULL);
    RLC  = new ParameterG("RLC",  "Release Complete",      DLR,SLR,NULL);
    DT1  = new ParameterG("DT1",  "Data Form 1",           DLR,SEG,DATA,NULL);
    DT2  = new ParameterG("DT2",  "Data Form 2",           DLR,SEQ,DATA,NULL);
    AK   = new ParameterG("AK",   "Data Acknowledgement",  DLR,PRN,CREDIT,NULL);
    UDT  = new ParameterG("UDT",  "Unitdata",              PCL,CDPA,CGPA,UPART,NULL);
    UDTS = new ParameterG("UDTS", "Unitdata Service",      RETC,CDPA,CGPA,UPART,NULL);
    ED   = new ParameterG("ED",   "Expedited Data",        DLR,DATA,NULL);
    EA   = new ParameterG("EA",   "Expedited Data Acknow", DLR,NULL);
    RSR  = new ParameterG("RSR",  "Reset Request",         DLR,SLR,RSTC,NULL);
    RSC  = new ParameterG("RSC",  "Reset Confirmation",    DLR,SLR,NULL);
    ERR  = new ParameterG("ERR",  "Proto Data Unit Error", DLR,ERRC,NULL);
    IT   = new ParameterG("IT",   "Inactivity Test",       DLR,SLR,PCL,SEQ,CREDIT,NULL);
    XUDT = new ParameterG("XUDT", "Extended Unitdata",     PCL,SCCPHOP,CDPA,CGPA,UPART,OPARMS,NULL);
    XUDS = new ParameterG("XUDS", "Extended Unitdata Srv", RETC,SCCPHOP,CDPA,CGPA,UPART,OPARMS,NULL);
    
    MT   = new Field("MT","Message Type",8,0);
    MT_B = new Bra("MT:","Message Type Branch",(Codec*)MT,
            CR  , 1, CC  , 2, CREF, 3, RLSD, 4, RLC , 5, DT1 , 6,
            DT2 , 7, AK  , 8, UDT , 9, UDTS,10, ED  ,11, EA  ,12,
            RSR ,13, RSC ,14, ERR ,15, IT  ,16, XUDT,17, XUDS,18,
        NULL);
};

Codec_CPA
SCCP_CPA("CPA","SCCP Call Party Addr");
