///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2023 Ericsson Telecom AB
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
///////////////////////////////////////////////////////////////////////////////
//
//  File:               MobileL3_SMS_Types.ttcn
//  Rev:                R2A
//  Prodnr:             CNL 113 832
//  Contact:            http://ttcn.ericsson.se
//  Reference:          3GPP TS 24.008 v13.4.0, 24.011 v13.0.0, 23.040 v13.0.0

module MobileL3_SMS_Types
{
// beginning of module

// This module contains the SMS Messages defined in 24.011 v13.0.0,
// 23.040 v13.0.0 and 23.038 v7.0.0
// This includes the C-PDUs, R-PDUs and T-PDUs with attributes for
// RAW encoding/decoding.


import from General_Types all;

external function enc_TPDU_RP_DATA_MS_SGSN_fast(in TPDU_RP_DATA_MS_SGSN pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_TPDU_RP_DATA_MS_SGSN_backtrack(in octetstring stream, out TPDU_RP_DATA_MS_SGSN pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_TPDU_RP_DATA_SGSN_MS_fast(in TPDU_RP_DATA_SGSN_MS pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_TPDU_RP_DATA_SGSN_MS_backtrack(in octetstring stream, out TPDU_RP_DATA_SGSN_MS pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_TPDU_RP_ACK_MS_SGSN_fast(in TPDU_RP_ACK_MS_SGSN pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_TPDU_RP_ACK_MS_SGSN_backtrack(in octetstring stream, out TPDU_RP_ACK_MS_SGSN pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_TPDU_RP_ACK_SGSN_MS_fast(in TPDU_RP_ACK_SGSN_MS pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_TPDU_RP_ACK_SGSN_MS_backtrack(in octetstring stream, out TPDU_RP_ACK_SGSN_MS pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_TPDU_RP_ERROR_MS_SGSN_fast(in TPDU_RP_ERROR_MS_SGSN pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_TPDU_RP_ERROR_MS_SGSN_backtrack(in octetstring stream, out TPDU_RP_ERROR_MS_SGSN pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_TPDU_RP_ERROR_SGSN_MS_fast(in TPDU_RP_ERROR_SGSN_MS pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_TPDU_RP_ERROR_SGSN_MS_backtrack(in octetstring stream, out TPDU_RP_ERROR_SGSN_MS pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_RPDU_SGSN_MS_fast(in RPDU_SGSN_MS pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_RPDU_SGSN_MS_backtrack(in octetstring stream, out RPDU_SGSN_MS pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }

external function enc_RPDU_MS_SGSN_fast(in RPDU_MS_SGSN pdu, out octetstring stream)
with { extension "prototype(fast)" extension "encode(RAW)" }

external function dec_RPDU_MS_SGSN_backtrack(in octetstring stream, out RPDU_MS_SGSN pdu) return integer
with { extension "prototype(backtrack)" extension "decode(RAW)" }
//==============================================================================
// 24.011 7.2 CP-MESSAGES (CP_DATA, CP_ACK, CP_ERROR)
//==============================================================================

// 7.2
type union L3_SMS_MS_SGSN
{
  CP_DATA_MS_SGSN    cP_DATA,
  CP_ACK             cP_ACK,
  CP_ERROR           cP_ERROR
};

// 7.2
type union L3_SMS_SGSN_MS
{
  CP_DATA_SGSN_MS    cP_DATA,
  CP_ACK             cP_ACK,
  CP_ERROR           cP_ERROR
};

// 7.2.1 CP-DATA
type record CP_DATA_MS_SGSN
{
  BIT8                         cP_messageType,
  CP_User_DataLV_MS_SGSN       cP_User_Data
} with { variant "PRESENCE(cP_messageType = '00000001'B)"; };

// 7.2.1 CP-DATA
type record CP_DATA_SGSN_MS
{
  BIT8                         cP_messageType,
  CP_User_DataLV_SGSN_MS       cP_User_Data
} with { variant "PRESENCE(cP_messageType = '00000001'B)"; };

// 7.2.2 CP-ACK
type record CP_ACK
{
  BIT8                         cP_messageType
} with { variant "PRESENCE(cP_messageType = '00000100'B)"; };

// 7.2.3 CP-ERROR
type record CP_ERROR
{
  BIT8                         cP_messageType,
  CP_CauseV                    cP_Cause
} with { variant "PRESENCE(cP_messageType = '00010000'B)"; };

// 7.2.1 CP-DATA
type record CP_User_DataLV_SGSN_MS
{
  LIN1               lengthIndicator,
  RPDU_SGSN_MS       cP_RPDU
} with { variant (lengthIndicator) "LENGTHTO (cP_RPDU)"};

// 7.2.1 CP-DATA
type record CP_User_DataLV_MS_SGSN
{
  LIN1               lengthIndicator,
  RPDU_MS_SGSN       cP_RPDU
} with { variant (lengthIndicator) "LENGTHTO (cP_RPDU)"};

// 7.2.3 CP-ERROR
type record CP_CauseV
{
  OCT1               causeValue
}


//=============================================================================
//  END OF CP-MESSAGES
//=============================================================================


//=============================================================================
// 24.011  7.3  RP-MESSAGES (RP-DATA, RP-SMMA, RP-ACK, RP-ERROR)
//=============================================================================
// 7.3
type union RPDU_SGSN_MS
{
  RP_DATA_SGSN_MS              rP_DATA_SGSN_MS,
  RP_ACK_SGSN_MS               rP_ACK_SGSN_MS,
  RP_ERROR_SGSN_MS             rP_ERROR_SGSN_MS,
  RP_SMMA                      rP_SMMA // RP_SMMA included for negative testing in SGSN_MS direction
} with {
  variant  "TAG
  (
   rP_DATA_SGSN_MS,  rP_MTI = '001'B;
   rP_ACK_SGSN_MS,   rP_MTI = '011'B;
   rP_ERROR_SGSN_MS, rP_MTI = '101'B;
   rP_SMMA,          rP_MTI = '110'B;
  )"
};

// 7.3
type union RPDU_MS_SGSN
{
  RP_DATA_MS_SGSN              rP_DATA_MS_SGSN,
  RP_ACK_MS_SGSN               rP_ACK_MS_SGSN,
  RP_ERROR_MS_SGSN             rP_ERROR_MS_SGSN,
  RP_SMMA                      rP_SMMA
} with {
  variant  "TAG
  (
   rP_DATA_MS_SGSN,  rP_MTI = '000'B;
   rP_ACK_MS_SGSN,   rP_MTI = '010'B;
   rP_ERROR_MS_SGSN, rP_MTI = '100'B;
   rP_SMMA,          rP_MTI = '110'B;
  )"
};

// 7.3.1.2 RP-DATA (Mobile Station to Network)
type record RP_DATA_MS_SGSN
{
  BIT3                         rP_MTI,
  BIT5                         rP_Spare,  // '00000'B
  OCT1                         rP_MessageReference,
  RP_OriginatorAddressLV       rP_OriginatorAddress,
  RP_DestinationAddressLV      rP_DestinationAddress,
  RP_DATA_User_DataLV_MS_SGSN  rP_User_Data
} with { variant "PRESENCE(rP_MTI = '000'B)"; };

// 7.3.1.1 RP-DATA (Network to Mobile Station)
type record RP_DATA_SGSN_MS
{
  BIT3                         rP_MTI,
  BIT5                         rP_Spare,  // '00000'B
  OCT1                         rP_MessageReference,
  RP_OriginatorAddressLV       rP_OriginatorAddress,
  RP_DestinationAddressLV      rP_DestinationAddress,
  RP_DATA_User_DataLV_SGSN_MS  rP_User_Data
} with { variant "PRESENCE(rP_MTI = '001'B)"; };

// 7.3.2 RP-SMMA
type record RP_SMMA
{
  BIT3                         rP_MTI,
  BIT5                         rP_Spare,   // '00000'B
  OCT1                         rP_MessageReference
} with { variant "PRESENCE(rP_MTI = '110'B)"; };

// 7.3.3 RP-ACK
type record RP_ACK_SGSN_MS
{
  BIT3                         rP_MTI,
  BIT5                         rP_Spare,   // '00000'B
  OCT1                         rP_MessageReference,
  RP_ACK_User_DataTLV_SGSN_MS  rP_User_Data     optional
} with { variant "PRESENCE(rP_MTI = '011'B)"; };

// 7.3.3 RP-ACK
type record RP_ACK_MS_SGSN
{
  BIT3                         rP_MTI,
  BIT5                         rP_Spare,   // '00000'B
  OCT1                         rP_MessageReference,
  RP_ACK_User_DataTLV_MS_SGSN  rP_User_Data     optional
} with { variant "PRESENCE(rP_MTI = '010'B)"; };

// 7.3.4 RP-ERROR
type record RP_ERROR_SGSN_MS
{
  BIT3                                   rP_MTI,
  BIT5                                   rP_Spare,   // '00000'B
  OCT1                                   rP_Message_Reference,
  RP_CauseLV                             rP_CauseLV,
  RP_ERROR_User_DataTLV_SGSN_MS          rP_User_Data    optional
} with { variant "PRESENCE(rP_MTI = '101'B)"; };

// 7.3.4 RP-ERROR
type record RP_ERROR_MS_SGSN
{
  BIT3                                    rP_MTI,
  BIT5                                    rP_Spare,   // '00000'B
  OCT1                                    rP_Message_Reference,
  RP_CauseLV                              rP_CauseLV,
  RP_ERROR_User_DataTLV_MS_SGSN           rP_User_Data     optional
} with { variant "PRESENCE(rP_MTI = '100'B)"; };

// 8.2.5.1 Originator address element
type record RP_OriginatorAddressLV
{
  LIN1                                 lengthIndicator,
  RP_NumberingPlan_and_NumberDigits    rP_OriginatorAddress optional
} with {variant(lengthIndicator)"LENGTHTO (rP_OriginatorAddress)"};


// 8.2.5.2 Destination address element
type record RP_DestinationAddressLV
{
  LIN1                                lengthIndicator,
  RP_NumberingPlan_and_NumberDigits   rP_DestinationAddress optional
} with { variant (lengthIndicator)"LENGTHTO (rP_DestinationAddress)"};

// 8.2.5.1 & 8.2.5.2 Originator address element
type record RP_NumberingPlan_and_NumberDigits
{
  BIT4                         rP_NumberingPlanIdentification,
  BIT3                         rP_TypeOfNumber,
  BIT1                         rP_Ext,
  hexstring                    rP_NumberDigits  length (1..20)
} with { variant "PADDING(yes)";
         variant "PADDING_PATTERN('1111'B)"};


// 8.2.5.4 RP-Cause element
type record RP_CauseLV
{
  LIN1               rP_LengthIndicator,
  RP_CauseV          rP_CauseV,
  OCT1               rP_diagnisticField   optional
} with { variant (rP_LengthIndicator)"LENGTHTO (rP_CauseV,rP_diagnisticField)"};

// 8.2.5.4 RP-Cause
type record RP_CauseV
{
  BIT7               causeValue,
  BIT1               ext     //'0'B
}

// 8.2.5.3 RP-User data element
type record RP_DATA_User_DataLV_SGSN_MS
{
  LIN1                         rP_LengthIndicator,
  TPDU_RP_DATA_SGSN_MS         rP_TPDU
} with { variant (rP_LengthIndicator) "LENGTHTO (rP_TPDU)"};

// 8.2.5.3 RP-User data element
type record RP_DATA_User_DataLV_MS_SGSN
{
  LIN1                         rP_LengthIndicator,
  TPDU_RP_DATA_MS_SGSN         rP_TPDU
} with { variant (rP_LengthIndicator) "LENGTHTO (rP_TPDU)"};

// 8.2.5.3 RP-User data element
type record RP_ACK_User_DataTLV_SGSN_MS
{
  BIT1                         rP_Spare,
  BIT7                         rP_UserDataIEI,
  LIN1                         rP_LengthIndicator,
  TPDU_RP_ACK_SGSN_MS          rP_TPDU
} with { variant "PRESENCE(rP_UserDataIEI = '1000001'B)";
         variant (rP_Spare,rP_UserDataIEI)  "FIELDORDER(msb)";
         variant (rP_LengthIndicator) "LENGTHTO (rP_TPDU)"};

// 8.2.5.3 RP-User data element
type record RP_ACK_User_DataTLV_MS_SGSN
{
  BIT1                         rP_Spare,
  BIT7                         rP_UserDataIEI,
  LIN1                         rP_LengthIndicator,
  TPDU_RP_ACK_MS_SGSN          rP_TPDU
} with { variant "PRESENCE(rP_UserDataIEI = '1000001'B)";
         variant (rP_Spare,rP_UserDataIEI)  "FIELDORDER(msb)";
         variant (rP_LengthIndicator) "LENGTHTO (rP_TPDU)"};

// 8.2.5.3 RP-User data element
type record RP_ERROR_User_DataTLV_SGSN_MS
{
  BIT1                         rP_Spare,
  BIT7                         rP_UserDataIEI,
  LIN1                         rP_LengthIndicator,
  TPDU_RP_ERROR_SGSN_MS        rP_TPDU
} with { variant "PRESENCE(rP_UserDataIEI = '1000001'B)";
         variant (rP_Spare,rP_UserDataIEI)  "FIELDORDER(msb)";
         variant (rP_LengthIndicator) "LENGTHTO (rP_TPDU)"};

// 8.2.5.3 RP-User data element
type record RP_ERROR_User_DataTLV_MS_SGSN
{
  BIT1                         rP_Spare,
  BIT7                         rP_UserDataIEI,
  LIN1                         rP_LengthIndicator,
  TPDU_RP_ERROR_MS_SGSN        rP_TPDU
} with { variant "PRESENCE(rP_UserDataIEI = '1000001'B)";
         variant (rP_Spare,rP_UserDataIEI)  "FIELDORDER(msb)";
         variant (rP_LengthIndicator) "LENGTHTO (rP_TPDU)"};


type union TPDU_RP_DATA_MS_SGSN
{
  SMS_SUBMIT                   sMS_SUBMIT,
  SMS_COMMAND                  sMS_COMMAND
} with {
  variant  "TAG
  (
   sMS_SUBMIT,  tP_MTI =  '01'B;
   sMS_COMMAND, tP_MTI =  '10'B;
  )"
};


type union TPDU_RP_DATA_SGSN_MS
{
  SMS_DELIVER                  sMS_DELIVER,
  SMS_STATUS_REPORT            sMS_STATUS_REPORT
} with {
  variant  "TAG
  (
   sMS_DELIVER,  tP_MTI =  '00'B;
   sMS_STATUS_REPORT, tP_MTI =  '10'B;
  )"
};


type union TPDU_RP_ACK_MS_SGSN
{
  SMS_DELIVER_REPORT_in_RP_ACK           sMS_DELIVER_REPORT
} with {
  variant  "TAG
  (
   sMS_DELIVER_REPORT,  tP_MTI =  '00'B;
  )"
};


type union TPDU_RP_ACK_SGSN_MS
{
  SMS_SUBMIT_REPORT_in_RP_ACK            sMS_SUBMIT_REPORT
} with {
  variant  "TAG
  (
   sMS_SUBMIT_REPORT,  tP_MTI =  '01'B;
  )"
};


type union TPDU_RP_ERROR_MS_SGSN
{
  SMS_DELIVER_REPORT_in_RP_ERROR         sMS_DELIVER_REPORT
} with {
  variant  "TAG
  (
   sMS_DELIVER_REPORT,  tP_MTI =  '00'B;
  )"
};


type union TPDU_RP_ERROR_SGSN_MS
{
  SMS_SUBMIT_REPORT_in_RP_ERROR          sMS_SUBMIT_REPORT
} with {
  variant  "TAG
  (
   sMS_SUBMIT_REPORT,  tP_MTI =  '01'B;
  )"
};


//================================================================
//  END OF  RP-MESSAGES
//================================================================


//================================================================
//  TPDUs    23.040  9.2.2
// (SMS_DELIVER, SMS_DELIVER_REPORT, SMS_SUBMIT, SMS_SUBMIT_REPORT,
//  SMS_STATUS_REPORT, SMS_COMMAND)
//================================================================

// 23.040 9.2.2.1
type record SMS_DELIVER
{
  BIT2                         tP_MTI,
  BIT1                         tP_MMS,
  BIT1                         tP_LP,
  BIT1                         tP_Spare, //00
  BIT1                         tP_SRI,
  BIT1                         tP_UDHI,
  BIT1                         tP_RP,

  TP_OA                        tP_OA,

  OCT1                         tP_PID,

  TP_DCS                       tP_DCS,
  //See 23.038 Section 4 for encoding tP_DCS
  OCT7                         tP_SCTS,

  TP_UDL_UD                    tP_UDL_UD
} with { variant "PRESENCE(tP_MTI =  '00'B)"; };

// 23.040 9.2.2.1a(i)
type record SMS_DELIVER_REPORT_in_RP_ERROR
{
  BIT2                         tP_MTI,
  BIT4                         tP_Spare1,  //'0000'B
  BIT1                         tP_UDHI,
  BIT1                         tP_Spare2,  //'0'B

  OCT1                         tP_FCS,

  BIT1                         tP_PresenceBitTP_PID,
  BIT1                         tP_PresenceBitTP_DCS,
  BIT1                         tP_PresenceBitTP_UDL,
  BIT4                         tP_Reserved,
  BIT1                         tP_ExtensionBit,
  // note:current implementation PID is 1 octet ->tP_extensionBit=0
  OCT1                         tP_PID        optional,
  //See 23.038 for encoding tP_DCS
  TP_DCS                       tP_DCS        optional,

  TP_UDL_UD                    tP_UDL_UD     optional
} with { variant "PRESENCE(tP_MTI =  '00'B)";
         variant (tP_PID)           "PRESENCE(tP_PresenceBitTP_PID = '1'B)";
         variant (tP_DCS)           "PRESENCE(tP_PresenceBitTP_DCS = '1'B)";
         variant (tP_UDL_UD)        "PRESENCE(tP_PresenceBitTP_UDL = '1'B)"};

// 23.040 9.2.2.1a(ii)
type record SMS_DELIVER_REPORT_in_RP_ACK
{
  BIT2                         tP_MTI,
  BIT4                         tP_Spare1,  //'0000'B
  BIT1                         tP_UDHI,
  BIT1                         tP_Spare2,  //'0'B

  BIT1                         tP_PresenceBitTP_PID,
  BIT1                         tP_PresenceBitTP_DCS,
  BIT1                         tP_PresenceBitTP_UDL,
  BIT4                         tP_Reserved,
  BIT1                         tP_ExtensionBit,
  // note:current implementation PID is 1 octet ->tP_extensionBit=0
  OCT1                         tP_PID     optional,
  //See 23.038 for encoding tP_DCS
  TP_DCS                       tP_DCS     optional,

  TP_UDL_UD                    tP_UDL_UD  optional
} with { variant "PRESENCE(tP_MTI =  '00'B)";
         variant (tP_PID)           "PRESENCE(tP_PresenceBitTP_PID = '1'B)";
         variant (tP_DCS)           "PRESENCE(tP_PresenceBitTP_DCS = '1'B)";
         variant (tP_UDL_UD)        "PRESENCE(tP_PresenceBitTP_UDL = '1'B)"};

// 23.040 9.2.2.2
type record SMS_SUBMIT
{
  BIT2                         tP_MTI,
  BIT1                         tP_RD,
  BIT2                         tP_VPF,
  BIT1                         tP_SRR,
  BIT1                         tP_UDHI,
  BIT1                         tP_RP,
  OCT1                         tP_MR,

  TP_DA                        tP_DA,

  OCT1                         tP_PID,
  //See 23.038 for encoding tP_DCS
  TP_DCS                       tP_DCS,

  TP_VP                        tP_VP optional,  // depends on tP_VPF

  TP_UDL_UD                    tP_UDL_UD
} with { variant "PRESENCE(tP_MTI =  '01'B)";
         variant (tP_VP)"CROSSTAG(
//           tP_VP_not_present,         tP_VPF='00'B;
           tP_VP_relative_format,     tP_VPF='10'B;
           tP_VP_enhanced_format,     tP_VPF='01'B;
           tP_VP_absolute_format,     tP_VPF='11'B
         )";
         variant (tP_VP) "PRESENCE(tP_VPF='10'B, tP_VPF='01'B, tP_VPF='11'B)"
         };

// 23.040 9.2.2.2a (i)
type record SMS_SUBMIT_REPORT_in_RP_ERROR    // for RP_Error
{
  BIT2                         tP_MTI,
  BIT4                         tP_Spare1,
  BIT1                         tP_UDHI,
  BIT1                         tP_Spare2,

  OCT1                         tP_FCS,

  BIT1                         tP_PresenceBitTP_PID,
  BIT1                         tP_PresenceBitTP_DCS,
  BIT1                         tP_PresenceBitTP_UDL,
  BIT4                         tP_Reserved,
  BIT1                         tP_ExtensionBit,
  // note:current implementation PID is 1 octet ->tP_extensionBit=0

  OCT7                         tP_SCTS,

  OCT1                         tP_PID           optional,
 //See 23.038 for encoding tP_DCS
  TP_DCS                       tP_DCS           optional,

  TP_UDL_UD                    tP_UDL_UD        optional
} with { variant "PRESENCE(tP_MTI =  '01'B)";
         variant (tP_PID)            "PRESENCE(tP_PresenceBitTP_PID = '1'B)";
         variant (tP_DCS)            "PRESENCE(tP_PresenceBitTP_DCS = '1'B)";
         variant (tP_UDL_UD)         "PRESENCE(tP_PresenceBitTP_UDL = '1'B)"}

// 23.040 9.2.2.2a (ii)
type record SMS_SUBMIT_REPORT_in_RP_ACK    // for RP_ACK
{
  BIT2                         tP_MTI,
  BIT4                         tP_Spare1,
  BIT1                         tP_UDHI,
  BIT1                         tP_Spare2,

  BIT1                         tP_PresenceBitTP_PID,
  BIT1                         tP_PresenceBitTP_DCS,
  BIT1                         tP_PresenceBitTP_UDL,
  BIT4                         tP_Reserved,
  BIT1                         tP_ExtensionBit,
  // note:current implementation PID is 1 octet ->tP_extensionBit=0
  OCT7                         tP_SCTS,

  OCT1                         tP_PID          optional,
  //See 23.038 for encoding tP_DCS
  TP_DCS                       tP_DCS          optional,

  TP_UDL_UD                    tP_UDL_UD       optional
} with { variant "PRESENCE(tP_MTI =  '01'B)";
         variant (tP_PID)            "PRESENCE(tP_PresenceBitTP_PID = '1'B)";
         variant (tP_DCS)            "PRESENCE(tP_PresenceBitTP_DCS = '1'B)";
         variant (tP_UDL_UD)         "PRESENCE(tP_PresenceBitTP_UDL = '1'B)"}

// 23.040 9.2.2.3
type record SMS_STATUS_REPORT
{
  BIT2                         tP_MTI,
  BIT1                         tP_MMS,
  BIT1                         tP_LP,
  BIT1                         tP_Spare1,
  BIT1                         tP_SRQ,
  BIT1                         tP_UDHI,
  BIT1                         tP_Spare2,

  OCT1                         tP_MR,

  TP_RA                        tP_RA,

  OCT7                         tP_SCTS,

  OCT7                         tP_DT,

  OCT1                         tP_ST,

  BIT1                         tP_PresenceBitTP_PID optional,
  BIT1                         tP_PresenceBitTP_DCS optional,
  BIT1                         tP_PresenceBitTP_UDL optional,
  BIT4                         tP_Reserved          optional,
  BIT1                         tP_ExtensionBit      optional,
  // note:current implementation PID is 1 octet ->tP_extensionBit=0
  OCT1                         tP_PID               optional,

  TP_DCS                       tP_DCS               optional,
  //See 23.038 for encoding tP_DCS
  TP_UDL_UD                    tP_UDL_UD            optional
} with { variant "PRESENCE(tP_MTI =  '10'B)";
         variant (tP_PID)    "PRESENCE(tP_PresenceBitTP_PID = '1'B)";
         variant (tP_DCS)    "PRESENCE(tP_PresenceBitTP_DCS = '1'B)";
         variant (tP_UDL_UD) "PRESENCE(tP_PresenceBitTP_UDL = '1'B)"}

// 23.040 9.2.2.4
type record SMS_COMMAND
{
  BIT2                         tP_MTI,
  BIT3                         tP_Spare1,
  BIT1                         tP_SRR,
  BIT1                         tP_UDHI,
  BIT1                         tP_Spare2,

  OCT1                         tP_MR,

  OCT1                         tP_PID,

  OCT1                         tP_CT,

  OCT1                         tP_MN,

  TP_DA                        tP_DA,

  TP_CDL_CD                    tP_CDL_CD
} with { variant "PRESENCE(tP_MTI =  '10'B)"; };
//================================================================
//   END OF  TPDUs    23.040  9.2.2
//================================================================

//================================================================
// TPDU Parameters  23.040 9.2.3
//================================================================
type record TP_OA
{
  TP_OA_NoPad   tP_OA_NoPad
} with { variant "PADDING(yes), PADDING_PATTERN('1111'B)"};
//Note: Padding is handled automatically here.

type record TP_OA_NoPad
{
  LIN1                         tP_LengthIndicator,   //0-20
  BIT4                         tP_NumberingPlanID,
  BIT3                         tP_TypeOfNumber,
  BIT1                         tp_Spare,
  hexstring                    tP_OAValue  length (0..20)
  // Note: tP_OAValue does not incude the padding half-octet.
  // It includes only useful tP_OAValue digits.
  // Padding after tP_OAValue digits is handled
  // automatically and the tester does not see it in
  // the TTCN templates
} with { variant (tP_LengthIndicator) "LENGTHTO (tP_OAValue)";
         variant (tP_LengthIndicator) "UNIT(4)";};

type record TP_CDL_CD
{
  LIN1                         tP_CDL, //  length is possible
  octetstring                  tP_CD
} with { variant (tP_CDL) "LENGTHTO (tP_CD)"};

type record TP_RA
{
  TP_RA_NoPad        tP_RA_NoPad
} with { variant "PADDING(yes), PADDING_PATTERN('1111'B)"};
//Note: Padding is handled automatically here.

type record TP_RA_NoPad
{
  LIN1                         tP_LengthIndicator,   //0-20
  BIT4                         tP_NumberingPlanID,
  BIT3                         tP_TypeOfNumber,
  BIT1                         tp_Spare,
  hexstring                    tP_RAValue  length (0..20)
  // Note: tP_RAValue does not incude the padding half-octet.
  // It includes only useful tP_RAValue digits.
  // Padding after tP_RAValue digits is handled
  // automatically and the tester does not see it in
  // the TTCN templates
} with { variant (tP_LengthIndicator) "LENGTHTO (tP_RAValue)";
         variant (tP_LengthIndicator) "UNIT(4)";};

type union TP_VP 
{
//  OCT0                         tP_VP_not_present,
  OCT1                         tP_VP_relative_format,
  OCT7                         tP_VP_enhanced_format,
  OCT7                         tP_VP_absolute_format
};

type record TP_DA
{
  TP_DA_NoPad   tP_DA_NoPad
} with { variant "PADDING(yes), PADDING_PATTERN('1111'B)"};
//Note: Padding is handled automatically here.

type record TP_DA_NoPad
{
  LIN1                         tP_LengthIndicator,   //0-20
  BIT4                         tP_NumberingPlanID,
  BIT3                         tP_TypeOfNumber,
  BIT1                         tp_Spare,
  hexstring                    tP_DAValue  length (0..20)
  // Note: tP_DAValue does not incude the padding half-octet.
  // It includes only useful tP_DAValue digits.
  // Padding after tP_DAValue digits is handled
  // automatically and the tester does not see it in
  // the TTCN templates
} with { variant (tP_LengthIndicator) "LENGTHTO (tP_DAValue)";
         variant (tP_LengthIndicator) "UNIT(4)"; };


// Note that tP_LengthIndicator in TP_UDL_UD gives the data length in septets or
// octets. Septets are used for uncompressed GSM 7 bit default alphabet coding
// Octets are used for all other variations.
// IT IS NOT CALCULATED AUTOMATICALLY BY THE RAW CODER.
// This will not be a problem during decoding.
// For encoding correct messages the tester has to enter manually
// or calculate the correct tP_LengthIndicator with a function.
// Note also that the septet or octet choice depends on the various
// bit combinations in field TP_DCS. See 23.038 Section 4.
type record TP_UDL_UD
{
  integer            tP_LengthIndicator,  // could be zero length
  octetstring        tP_UD
}

// See 23.038 for encoding TP_DCS
// The various bit combinations in TP_DCS determine
// the coding of TP_UDL_UD
type OCT1 TP_DCS;

//================================================================
// END of TPDU Parameters  23.040 9.2.3
//================================================================

}//end of module
with {
extension "version R2A"
encode "RAW"
}

