///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2019 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:               LLC_Types.ttcn
//  Description:        This module contains the Logical Link Control protocol (LLC)
//                      44.064 v7.1.0 with attributes for RAW encoding/decoding.
//  Rev:                R3A
//  Prodnr:             CNL 113 577
//  Updated:            2008-01-22
//  Contact:            http://ttcn.ericsson.se
//  Reference:          3GPP TS 44.064 7.1.0

module LLC_Types
{

import from General_Types all;

external function enc_PDU_LLC(in PDU_LLC pdu) return octetstring;
external function dec_PDU_LLC(in octetstring stream,in boolean checkFCS := true) return PDU_LLC;


////////////////////////////////
// XID fields
////////////////////////////////
type record Version
{
  integer       version_value (0..15),
  BIT4          spare

} with {
  variant (version_value) "FIELDLENGTH(4)";
}

type octetstring IOV_UI length(4)

type octetstring IOV_I length(4)

type record T200
{
  BIT4          spare,
  integer       t200Value
} with {
  variant (t200Value) "FIELDLENGTH(12)";
  variant (t200Value) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
};

type record N200
{
  integer       retransmissions (0..15),
  BIT4          spare
} with {
  variant (retransmissions) "FIELDLENGTH(4)";
};

type record N201_U
{
  BIT5          spare,
  integer       n201UValue
} with {
  variant (n201UValue) "FIELDLENGTH(11)";
  variant (n201UValue) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
};

type record N201_I
{
  BIT5          spare,
  integer       n201IValue
} with {
  variant (n201IValue) "FIELDLENGTH(11)";
  variant (n201IValue) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
};

type record MD
{
  BIT1          spare,
  integer       mDValue
} with {
  variant (mDValue) "FIELDLENGTH(15)";
  variant (mDValue) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
};

type record MU
{
  BIT1          spare,
  integer       mUValue
} with {
  variant (mUValue) "FIELDLENGTH(15)";
  variant (mUValue) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
};

type integer KD with {variant  "FIELDLENGTH(8)";};

type integer KU with {variant  "FIELDLENGTH(8)";};

type octetstring L3param;

type octetstring Reset_LLC length(0);

type union XID_Data
{
  Version       version,
  IOV_UI        iOV_UI,
  IOV_I         iOV_I,
  T200          t200,
  N200          n200,
  N201_U        n201_U,
  N201_I        n201_I,
  MD            mD,
  MU            mU,
  KD            kD,
  KU            kU,
  L3param       l3param,
  Reset_LLC     reset
}

type union  XID_length
{
  integer short_len,
  integer long_len
} with {
  variant (short_len) "FIELDLENGTH(2)";
  variant (long_len)  "FIELDLENGTH(8)";
  variant (long_len)  "BYTEORDER(last)";
  variant (short_len) "FIELDORDER(msb)";
  variant (long_len)  "FIELDORDER(msb)";
}

type record XID
{
  BIT1          xl,
  BIT5          typefield,
  XID_length    xID_length,
//  Header_XID    header_XID,
  XID_Data      xID_Data
} with {
  variant (xID_Data) "CROSSTAG(
                        version,  typefield = '00000'B;
                        iOV_UI,   typefield = '00001'B;
                        iOV_I,    typefield = '00010'B;
                        t200,     typefield = '00011'B;
                        n200,     typefield = '00100'B;
                        n201_U,   typefield = '00101'B;
                        n201_I,   typefield = '00110'B;
                        mD,       typefield = '00111'B;
                        mU,       typefield = '01000'B;
                        kD,       typefield = '01001'B;
                        kU,       typefield = '01010'B;
                        l3param,  typefield = '01011'B;
                        reset,    typefield = '01100'B;
                     )";
  variant  "FIELDORDER(msb)";
  variant (xID_length) "CROSSTAG( short_len,  xl = '0'B;
                                  long_len,   xl = '1'B;)";
  variant (xID_length) "LENGTHTO (xID_Data)"
  variant (xID_length) "PADDING(yes)"
};


////////////////////////////////
// Rejected Frame Control fields
////////////////////////////////
type record RejectedFrameControlField_UI
{
  Control_field_UI      control_field,
  OCT4                  spare
}


type record RejectedFrameControlField_U
{
  Control_field_U       control_field,
  OCT5                  spare
}


type union RejectedFrameControlField
{
  RejectedFrameControlField_UI   rejectedFrameControlField_UI,
  RejectedFrameControlField_U    rejectedFrameControlField_U
} with {
  variant "TAG(rejectedFrameControlField_UI, control_field.format = '110'B;
               rejectedFrameControlField_U,  control_field.format = '111'B;
               )";
};


////////////////////////////////
// Information fields
////////////////////////////////
type record of XID UA_Information;

type record of XID SABM_Information;

type record of XID XID_Information;

type octetstring DM_Information length(0);

type octetstring NULL_Information length(0);

type octetstring DISC_Information length(0);

type record FRMR_Information
{
  RejectedFrameControlField   rejectedFrameControlField,
  BIT4          spare1,
  BIT9          vS,
  BIT1          spare2,
  BIT9          vR,
  BIT1          cR,
  BIT4          spare3,
  BIT1          w4,
  BIT1          w3,
  BIT1          w2,
  BIT1          w1
} with {
  variant (vS) "BYTEORDER(last)";
  variant (vR) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
};


////////////////////////////////
// Information fields
////////////////////////////////
type record Address_field
{
  BIT4          sAPI,
  BIT2          spare,    // '00'B
  BIT1          cR,
  BIT1          pD      //'0' for LLC
}

type record Control_field_U
{
  BIT4          mBits,
  BIT1          pF,
  BIT3          format   // '111'B
}

type record Control_field_UI
{
  BIT3          format,        // '110'B
  BIT2          spare,
  integer       nU,     //BIT9
  BIT1          e,
  BIT1          pM
} with {

  variant (nU) "FIELDLENGTH(9)";
  variant (nU) "BYTEORDER(last)";
  variant  "FIELDORDER(msb)";
}

type union Information_field_U
{
  UA_Information        uA,
  SABM_Information      sABM,
  FRMR_Information      fRMR,
  DM_Information        dM,
  XID_Information       xID,
  NULL_Information	nULL,
  DISC_Information	dISC
};


////////////////////////////////
// PDU definitions
////////////////////////////////
type record PDU_LLC_UI
{
  Address_field         address_field,
  Control_field_UI      control_field,
  octetstring           information_field_UI,
  OCT3                  fCS    optional
  // fCS ENCODING:
  //'000000'O in send template -> generate CRC,
  // omit in send template -> generate CRC,
  // otherwise send out fCS in send template
  //
  // DECODING:
  // decoder generates '000000'O if CRC OK and if CRC check is requested
}

type record PDU_LLC_U
{
  Address_field         address_field,
  Control_field_U       control_field,
  Information_field_U   information_field_U,
  OCT3                  fCS    optional
  // ENCODING:
  //'000000'O in send template -> generate CRC,
  // omit in send template -> generate CRC,
  // otherwise send out fCS in send template
  //
  // DECODING:
  // decoder generates '000000'O if CRC OK and if CRC check is requested
} with {
  variant (information_field_U) "CROSSTAG( uA, control_field.mBits = '0110'B;
                                         sABM, control_field.mBits = '0111'B;
                                         fRMR, control_field.mBits = '1000'B;
                                           dM, control_field.mBits = '0001'B;
                                          xID, control_field.mBits = '1011'B;
					 nULL, control_field.mBits = '0000'B;
					 dISC, control_field.mBits = '0100'B;
                                          )";
};

type union PDU_LLC
{
  PDU_LLC_UI pDU_LLC_UI,
  PDU_LLC_U  pDU_LLC_U
} with   { variant "TAG (pDU_LLC_UI,  control_field.format ='110'B;
                          pDU_LLC_U,  control_field.format ='111'B;
                         )"
};

}with{ encode "RAW"}// end of module
