/******************************************************************************/
// @copyright   Copyright Notification
//   No part may be reproduced except as authorized by written permission.
//   The copyright and the foregoing restriction extend to reproduction in all media.
//   Trademark 2010, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC).
//   All rights reserved.
// @version: IWD_10wk37
// $Date: 2010-09-14 13:17:14 +0200 (Tue, 14 Sep 2010) $
// $Rev: 3870 $
/******************************************************************************/
module EUTRA_IdleMode
{
//=========================================================================
// Imports
//=========================================================================

  import from EUTRA_RRC_ASN1_Definitions language "ASN.1:1997" all;
  import from EUTRA_ASP_SrbDefs all;
  import from EUTRA_Component all;
  import from EUTRA_CommonDefs all;
  import from EUTRA_CommonProcedures all;
  import from EUTRA_AuxiliaryFunctions all;
  import from EUTRA_NASSteps all;
  import from EUTRA_RRCSteps all;
  import from EUTRA_SecurityFunctions all;
  import from EUTRA_SecuritySteps all;
  import from EUTRA_AspCommon_Templates all;
  import from EUTRA_SRB_Templates all;
  import from EUTRA_RRC_Templates all;
  import from CommonDefs all;
  import from NAS_CommonTypeDefs all;
  import from EPS_NAS_TypeDefs all;
  import from EPS_NAS_Constants all;
  import from EPS_NAS_MsgContainers all;
  import from EPS_NAS_Templates all;
  import from EUTRA_NASCommonFunctions all;
  import from EUTRA_Timing all;
  import from Parameters all;

//==============================================================================
// Types
//==============================================================================

  type CarrierFreqUTRA_FDD.p_MaxUTRA P_MaxUTRA_FDD;
  type CarrierFreqUTRA_FDD.q_QualMin Q_QualMin_FDD;

//==============================================================================
// Constants
//==============================================================================

  //Idle mode generic timer according to 36.523-3 cl. 7.8
  //* If timer expires, the default will catch it, fail and abort the test case
  const float tsc_IdleMode_GenericTimer := 360.0;               /* @status    APPROVED */

  //Tracking Area Codes used in Idle Mode Operations.
  //* Default values according to 36.523-1 cl. 6.0.1 Table 6.0.1-2
  const TrackingAreaCode tsc_IdleMode_TAC_Cell2  := int2bit (2, 16);    /* @status    APPROVED */
  const TrackingAreaCode tsc_IdleMode_TAC_Cell3  := int2bit (3, 16);    /* @status    APPROVED */
  const TrackingAreaCode tsc_IdleMode_TAC_Cell4  := int2bit (4, 16);
  const TrackingAreaCode tsc_IdleMode_TAC_Cell6  := int2bit (6, 16);    /* @status    APPROVED */
  const TrackingAreaCode tsc_IdleMode_TAC_Cell10 := int2bit (10, 16);
  const TrackingAreaCode tsc_IdleMode_TAC_Cell11 := int2bit (11, 16);
  const TrackingAreaCode tsc_IdleMode_TAC_Cell12 := int2bit (12, 16);
  const TrackingAreaCode tsc_IdleMode_TAC_Cell13 := int2bit (13, 16);
  const TrackingAreaCode tsc_IdleMode_TAC_Cell14 := int2bit (14, 16);

//==============================================================================
// Templates
//==============================================================================

  template (value) InterFreqCarrierFreqInfo cs_InterFreqCarrierFreq_Common ( CarrierFreqEUTRA                        p_EUTRA_CarrierFreq,
                                                                             Q_RxLevMin                              p_Q_RxLevMin,
                                                                             template (omit) P_Max                   p_P_Max,
                                                                             T_Reselection                           p_T_Reselection,
                                                                             template (omit) SpeedStateScaleFactors  p_T_ReselectionEUTRA_Sf,
                                                                             ReselectionThreshold                    p_ThreshX_High,
                                                                             ReselectionThreshold                    p_ThreshX_Low,
                                                                             AllowedMeasBandwidth                    p_AllowedMeasBandwidth,
                                                                             PresenceAntennaPort1                    p_PresenceAntennaPort1,
                                                                             template (omit) CellReselectionPriority p_CellReselectionPriority,
                                                                             NeighCellConfig                         p_NeighCellConfig,
                                                                             Q_OffsetRange                           p_Q_OffsetRange,
                                                                             template (omit) InterFreqNeighCellList  p_InterFreqNeighCellList,
                                                                             template (omit) InterFreqBlackCellList  p_InterFreqBlackCellList ) :=
  { /* @status    APPROVED */
    dl_CarrierFreq           := p_EUTRA_CarrierFreq.dl_CarrierFreq,
    q_RxLevMin               := p_Q_RxLevMin,
    p_Max                    := p_P_Max,
    t_ReselectionEUTRA       := p_T_Reselection,
    t_ReselectionEUTRA_SF    := p_T_ReselectionEUTRA_Sf,
    threshX_High             := p_ThreshX_High,
    threshX_Low              := p_ThreshX_Low,
    allowedMeasBandwidth     := p_AllowedMeasBandwidth,
    presenceAntennaPort1     := p_PresenceAntennaPort1,
    cellReselectionPriority  := p_CellReselectionPriority,
    neighCellConfig          := p_NeighCellConfig,
    q_OffsetFreq             := p_Q_OffsetRange,
    interFreqNeighCellList   := p_InterFreqNeighCellList,
    interFreqBlackCellList   := p_InterFreqBlackCellList
  };

  template (value) InterFreqCarrierFreqInfo cs_InterFreqCarrierFreq_CRPri ( CarrierFreqEUTRA                        p_EUTRA_CarrierFreq,
                                                                            AllowedMeasBandwidth                    p_AllowedMeasBandwidth,
                                                                            template (omit) CellReselectionPriority p_CellReselectionPriority ) :=
    /* @status    APPROVED */
    cs_InterFreqCarrierFreq_Common ( p_EUTRA_CarrierFreq,
                                     -65,
                                     omit,
                                     0,
                                     omit,
                                     2,
                                     1,
                                     p_AllowedMeasBandwidth,
                                     false,
                                     p_CellReselectionPriority,
                                     '01'B,
                                     dB0,
                                     omit,
                                     omit );
  
  template (value) InterFreqCarrierFreqInfo cs_InterFreqCarrierFreq_ThreshXHigh_CRPri ( CarrierFreqEUTRA                        p_EUTRA_CarrierFreq,
                                                                                        AllowedMeasBandwidth                    p_AllowedMeasBandwidth,
                                                                                        ReselectionThreshold                    p_ThreshX_High,
                                                                                        template (omit) CellReselectionPriority p_CellReselectionPriority ) :=
    /* @status    APPROVED */
    cs_InterFreqCarrierFreq_Common ( p_EUTRA_CarrierFreq,
                                     -65,
                                     omit,
                                     0,
                                     omit,
                                     p_ThreshX_High,
                                     1,
                                     p_AllowedMeasBandwidth,
                                     false,
                                     p_CellReselectionPriority,
                                     '01'B,
                                     dB0,
                                     omit,
                                     omit );
  
  template (value) InterFreqCarrierFreqInfo cs_InterFreqCarrierFreq_ThreshXHigh ( CarrierFreqEUTRA     p_EUTRA_CarrierFreq,
                                                                                  AllowedMeasBandwidth p_AllowedMeasBandwidth,
                                                                                  ReselectionThreshold p_ThreshX_High ) :=
    cs_InterFreqCarrierFreq_Common ( p_EUTRA_CarrierFreq,
                                     -65,
                                     omit,
                                     0,
                                     omit,
                                     p_ThreshX_High,
                                     1,
                                     p_AllowedMeasBandwidth,
                                     false,
                                     4,
                                     '01'B,
                                     dB0,
                                     omit,
                                     omit );
  
  template (value) CarrierFreqUTRA_FDD cs_CarrierFreqUTRA_FDD_Common ( ARFCN_ValueUTRA                         p_ARFCN_ValueUTRA,
                                                                       template (omit) CellReselectionPriority p_CellReselectionPriority,
                                                                       ReselectionThreshold                    p_ThreshX_High,
                                                                       ReselectionThreshold                    p_ThreshX_Low,
                                                                       Q_RxLevMin                              p_Q_RxLevMin,
                                                                       P_MaxUTRA_FDD                           p_P_MaxUTRA,
                                                                       Q_QualMin_FDD                           p_Q_QualMin ) :=
  {
    carrierFreq             := p_ARFCN_ValueUTRA,
    cellReselectionPriority := p_CellReselectionPriority,
    threshX_High            := p_ThreshX_High,
    threshX_Low             := p_ThreshX_Low,
    q_RxLevMin              := p_Q_RxLevMin,
    p_MaxUTRA               := p_P_MaxUTRA,
    q_QualMin               := p_Q_QualMin
  };

  template (value) CarrierFreqUTRA_TDD cs_CarrierFreqUTRA_TDD_Common ( ARFCN_ValueUTRA                         p_ARFCN_ValueUTRA,
                                                                       template (omit) CellReselectionPriority p_CellReselectionPriority,
                                                                       ReselectionThreshold                    p_ThreshX_High,
                                                                       ReselectionThreshold                    p_ThreshX_Low,
                                                                       Q_RxLevMin                              p_Q_RxLevMin,
                                                                       P_MaxUTRA_FDD                           p_P_MaxUTRA ) :=
  {
    carrierFreq             := p_ARFCN_ValueUTRA,
    cellReselectionPriority := p_CellReselectionPriority,
    threshX_High            := p_ThreshX_High,
    threshX_Low             := p_ThreshX_Low,
    q_RxLevMin              := p_Q_RxLevMin,
    p_MaxUTRA               := p_P_MaxUTRA
  };

  template (value) CarrierFreqUTRA_FDD cs_CarrierFreqUTRA_FDD_CRPrio ( ARFCN_ValueUTRA                         p_ARFCN_ValueUTRA,
                                                                       template (omit) CellReselectionPriority p_CellReselectionPriority ) :=
  cs_CarrierFreqUTRA_FDD_Common ( p_ARFCN_ValueUTRA,
                                  p_CellReselectionPriority,
                                  2,
                                  1,
                                  -40,
                                  21,
                                  -24 );

  template (value) CarrierFreqUTRA_FDD cs_CarrierFreqUTRA_FDD_CRPrio_PMax ( ARFCN_ValueUTRA                         p_ARFCN_ValueUTRA,
                                                                            template (omit) CellReselectionPriority p_CellReselectionPriority,
                                                                            P_MaxUTRA_FDD                           p_P_MaxUTRA ) :=
  cs_CarrierFreqUTRA_FDD_Common ( p_ARFCN_ValueUTRA,
                                  p_CellReselectionPriority,
                                  2,
                                  1,
                                  -40,
                                  p_P_MaxUTRA,
                                  -24 );

  template (value) CarrierFreqUTRA_TDD cs_CarrierFreqUTRA_TDD_CRPrio_PMax ( ARFCN_ValueUTRA                         p_ARFCN_ValueUTRA,
                                                                            template (omit) CellReselectionPriority p_CellReselectionPriority,
                                                                            P_MaxUTRA_FDD                           p_P_MaxUTRA ) :=
  cs_CarrierFreqUTRA_TDD_Common ( p_ARFCN_ValueUTRA,
                                  p_CellReselectionPriority,
                                  2,
                                  1,
                                  -40,
                                  p_P_MaxUTRA );

  template (value) CarrierFreqUTRA_TDD cs_CarrierFreqUTRA_TDD_CRPrio ( ARFCN_ValueUTRA                         p_ARFCN_ValueUTRA,
                                                                       template (omit) CellReselectionPriority p_CellReselectionPriority ) :=
  cs_CarrierFreqUTRA_TDD_Common ( p_ARFCN_ValueUTRA,
                                  p_CellReselectionPriority,
                                  2,
                                  1,
                                  -40,
                                  21 );

  template (value) CarrierFreqUTRA_FDD cs_CarrierFreqUTRA_FDD_ReselectionThreshold ( ARFCN_ValueUTRA      p_ARFCN_ValueUTRA,
                                                                                     ReselectionThreshold p_ReselectionThreshold ) :=
  cs_CarrierFreqUTRA_FDD_Common ( p_ARFCN_ValueUTRA,
                                  3,
                                  p_ReselectionThreshold,
                                  p_ReselectionThreshold,
                                  -40,
                                  21,
                                  -24 );

  template (value) CarrierFreqUTRA_TDD cs_CarrierFreqUTRA_TDD_ReselectionThreshold ( ARFCN_ValueUTRA      p_ARFCN_ValueUTRA,
                                                                                     ReselectionThreshold p_ReselectionThreshold ) :=
  cs_CarrierFreqUTRA_TDD_Common ( p_ARFCN_ValueUTRA,
                                  3,
                                  p_ReselectionThreshold,
                                  p_ReselectionThreshold,
                                  -40,
                                  21 );

  //Template ASPs to receive RRC message on SRB0 on any cell
  template SRB_COMMON_IND car_SRB0_RrcPdu_IND_AnyCell ( template (present) UL_CCCH_Message p_RrcPdu ) :=
  {
    Common := cr_IndAspCommonPart_SRB ( ?, tsc_SRB0 ),
    Signalling := {
      Rrc := {
        Ccch := p_RrcPdu
      },
      Nas := omit
    }
  };

  template UL_DCCH_Message cdr_RRCConnectionSetupComplete_2ndSelPlmnId ( template (present) RRC_TransactionIdentifier p_RRC_TI,
                                                                        template (present) DedicatedInfoNAS p_NAS_DedicatedInformation,
                                                                        template RegisteredMME p_RegisteredMME := *)
  modifies cr_508_RRCConnectionSetupComplete:=
  {
    message_ := {
      c1 := {
        rrcConnectionSetupComplete := {
          rrc_TransactionIdentifier := p_RRC_TI,
          criticalExtensions := {
            c1 := {
              rrcConnectionSetupComplete_r8 := {
                selectedPLMN_Identity    := 2
              }
            }
          }
        }
      }
    }
  };

  template (value) SystemInformationBlockType4 cs_SIB4_AllParameters ( template (omit) IntraFreqNeighCellList p_IntraFreqNeighCellList,
                                                                       template (omit) IntraFreqBlackCellList p_IntraFreqBlackCellList,
                                                                       template (omit) PhysCellIdRange        p_PhysCellIdRange ) :=
  { /* @status    APPROVED */
    intraFreqNeighCellList := p_IntraFreqNeighCellList,
    intraFreqBlackCellList := p_IntraFreqBlackCellList,
    csg_PhysCellIdRange    := p_PhysCellIdRange
  };
  
  template (value) SystemInformationBlockType4 cs_SIB4_Csg_PhysCellIdRange_StartOnly ( PhysCellId p_Start ) :=
    cs_SIB4_AllParameters (omit, omit, cs_PhysCellIdRange_StartOnly(p_Start));
  
  template (value) PhysCellIdRange cs_PhysCellIdRange_StartOnly ( PhysCellId p_Start ) := {
    start_ := p_Start,
    range := omit
  }
  
  template (value) SystemInformationBlockType4 cs_SIB4_NeighCellList ( template (value) IntraFreqNeighCellList p_IntraFreqNeighCellList) :=
    /* @status    APPROVED */
    cs_SIB4_AllParameters ( p_IntraFreqNeighCellList, omit, omit);
  
  template (value) SystemInformationBlockType4 cs_SIB4_Neigh_BlackCellList_1Entry ( template (value) IntraFreqNeighCellList p_IntraFreqNeighCellList,
                                                                                    template (value) IntraFreqBlackCellList p_IntraFreqBlackCellList ) :=
    cs_SIB4_AllParameters ( p_IntraFreqNeighCellList,
                            p_IntraFreqBlackCellList,
                            omit);

//==============================================================================
// Functions
//==============================================================================

  /*
   * @desc      Function used in Idle Mode test cases to perform Tracking Area Update on the new EUTRA cell.
   * @param     p_CellId .. The EUTRA cell on which the random access request and the TAU will happen
   * @status    APPROVED
   */
  function f_EUTRA_IdleMode_TAU ( CellId_Type p_CellId ) runs on EUTRA_PTC
  {
    timer t_IdleMode_GenericTimer := tsc_IdleMode_GenericTimer;

    t_IdleMode_GenericTimer.start;
    f_EUTRA_508CheckCampOnNewEutraCell ( p_CellId );
    t_IdleMode_GenericTimer.stop;
  }

  /*
   * @desc      Function used in Idle Mode test cases to perform Tracking Area Update on the new EUTRA cell upon
   *            mobility from another RAT
   * @param     p_CellId .. The EUTRA cell on which the random access request and the TAU will happen
   */
  function f_EUTRA_IdleMode_TAU_UponMobility_FromOtherRAT ( CellId_Type p_CellId ) runs on EUTRA_PTC
  {
    timer t_IdleMode_GenericTimer := tsc_IdleMode_GenericTimer;

    t_IdleMode_GenericTimer.start;
    f_EUTRA_508CheckCampOnNewEutraCellUponMobilityFromAnotherRAT ( p_CellId );
    t_IdleMode_GenericTimer.stop;
  }

  /*
   * @desc      Tracking area update behaviour according to 36.508 cl. 6.4.2.7
   * @param     p_CellId
   * @param     p_RRC_TI            (default value: tsc_RRC_TI_Def)
   * @param     p_ForcedAttach      (default value: NORMAL)
   * @status    APPROVED
   */
  function f_EUTRA_TrackingAreaUpdate_WithoutRrcConnReq ( CellId_Type               p_CellId,
                                                          RRC_TransactionIdentifier p_RRC_TI := tsc_RRC_TI_Def,
                                                          EUTRA_ATTACH_Type         p_ForcedAttach := NORMAL ) runs on EUTRA_PTC
  {
    var SRB_COMMON_IND v_ReceivedAsp;
    var NAS_MSG_Indication_Type v_NasInd;
    var ReleaseCause v_ReleaseCause := other;
    var NAS_KsiValue v_KsiValue := f_EUTRA_SecurityKSIasme_Get ( );
    var GutiParameters_Type v_GutiParams:= f_EUTRA_CellInfo_GetGuti ( p_CellId );
    var NAS_PlmnId v_PLMN := f_Asn2Nas_PlmnId (v_GutiParams.PLMN_Identity);
    var B3_Type v_EpsUpdate_TypeValue := f_GetEPSTAUType ( );
    var TrackingAreaCode v_Tac := f_EUTRA_CellInfo_GetTAC ( p_CellId );
    var NAS_Lac v_LAC := f_EUTRA_CellInfo_GetLocationAreaCode ( p_CellId );
    var EPS_BearerContextStatus v_EPS_ContextStatus;
    var template (omit) LocAreaId v_LAI := f_GetLAI ( v_PLMN, v_LAC );
    var template (omit) MobileIdentity v_MSId := f_GetMSId ( p_ForcedAttach );
    var template (value) TrackingAreaIdList v_TaiList := cds_TAIListNonConsecutive_tlv ( v_PLMN, { bit2oct(v_Tac) } );
    var template AdditionalUpdateType v_AdditionalUpdateType := f_GetAdditionalUpdateType ();  //used to follow TTCN3 v411 standard

    //Step 2: Send RRC Connection Setup on SRB0 (CCCH) and switch on UL grant assignments:
    f_EUTRA_RRC_ConnectionSetup_Def ( p_CellId, cs_TimingInfo_Now, p_RRC_TI );
    
    // UE shall establish SRB1 acc. to 36.331 cl. 5.3.3.4 and 5.3.9
    // UE enters RRC_CONNECTED state
    // SRB1 is established: no ciphering, no integrity protection for NAS/RRC
    
    //Step 3: Receive RRCConnectionSetupComplete which includes a TRACKING AREA UPDATE REQUEST message
    SRB.receive ( car_SRB1_RrcNasPdu_IND ( p_CellId,
                                           cr_508_RRCConnectionSetupComplete ( p_RRC_TI, ? ),
                                           cr_NAS_Indication ( tsc_SHT_IntegrityProtected,
                                                               cr_508_TAU_Request ( v_EpsUpdate_TypeValue,
                                                                                    v_KsiValue,
                                                                                    v_AdditionalUpdateType ))))
      -> value v_ReceivedAsp;
    
    v_NasInd := v_ReceivedAsp.Signalling.Nas[0];
    v_EPS_ContextStatus := v_NasInd.Pdu.Msg.tRACKING_AREA_UPDATE_REQUEST.epsBearerContextStatus; // Send this back in the Accept

    /* Step 4: Transmit TRACKING AREA UPDATE ACCEPT message */
    /* In case MME has the cached security context it verifies the TAU Request message
       and replies with TAU Accept message protected with the cached security context
       ( 33.401 cl. 9.1.2 Idle mode procedures in E-UTRAN ) */
    SRB.send ( cas_SRB1_NasPdu_REQ ( p_CellId,
                                     cs_TimingInfo_Now,
                                     cs_NAS_Request ( tsc_SHT_IntegrityProtected_Ciphered,
                                                      cs_508_TAU_Accept ( v_EpsUpdate_TypeValue,
                                                                          f_GutiParameters2MobileIdentity (tsc_IEI_Guti, v_GutiParams ),
                                                                          v_TaiList,
                                                                          v_EPS_ContextStatus,
                                                                          v_LAI,
                                                                          v_MSId,
                                                                          f_GetAdditionalUpdateResult(v_NasInd.Pdu.Msg.tRACKING_AREA_UPDATE_REQUEST.addUpdateType)) ) ) );
    
    /* Step 5: Receive TRACKING AREA UPDATE COMPLETE */
    /* According to 24.301 cl: 5.5.3.2.4:
       If the TRACKING AREA UPDATE ACCEPT message contained a GUTI,
       the UE shall return a TRACKING AREA UPDATE COMPLETE message to
       the MME to acknowledge the received GUTI */
    SRB.receive ( car_SRB1_NasPdu_IND ( p_CellId,
                                        cr_NAS_Indication ( tsc_SHT_IntegrityProtected_Ciphered,
                                                            cr_508_TAU_Complete ) ) );

    //Step 6: Release RRC connection
    f_EUTRA_RRC_ConnectionRelease ( p_CellId, p_RRC_TI, v_ReleaseCause );
  }
  
  /*
   * @desc      Tracking area update procedure without RRC Connection Release
   * @param     p_CellId
   * @param     p_RRC_TI
   * @param     p_ForcedAttach      (default value: NORMAL)
   * @status
   */
  function f_EUTRA_TrackingAreaUpdate_WithoutRelease ( CellId_Type               p_CellId,
                                                       RRC_TransactionIdentifier p_RRC_TI := tsc_RRC_TI_Def,
                                                       EUTRA_ATTACH_Type         p_ForcedAttach := NORMAL) runs on EUTRA_PTC
  {
    var NAS_MSG_Indication_Type v_NasInd;
    var EstablishmentCause v_EstablishmentCause := mo_Signalling;
    var NAS_KsiValue v_KsiValue := f_EUTRA_SecurityKSIasme_Get ( );
    var GutiParameters_Type v_GutiParams:= f_EUTRA_CellInfo_GetGuti ( p_CellId );
    var NAS_PlmnId v_PLMN := f_Asn2Nas_PlmnId ( v_GutiParams.PLMN_Identity );
    var B3_Type v_EpsUpdate_TypeValue := f_GetEPSTAUType( );
    var TrackingAreaCode v_Tac := f_EUTRA_CellInfo_GetTAC ( p_CellId );
    var NAS_Lac v_LAC := f_EUTRA_CellInfo_GetLocationAreaCode ( p_CellId );
    var EPS_BearerContextStatus v_EPS_ContextStatus;
    var template (omit) LocAreaId v_LAI := f_GetLAI ( v_PLMN, v_LAC );
    var template (omit) MobileIdentity v_MSId := f_GetMSId ( p_ForcedAttach );
    var template (value) TrackingAreaIdList v_TaiList := cds_TAIListNonConsecutive_tlv ( v_PLMN, { bit2oct( v_Tac ) } );
    var template AdditionalUpdateType v_AdditionalUpdateType := f_GetAdditionalUpdateType ();
    
    /* Step 1 - 3 */
    /* The TAU Request shall be integrity-protected, but not confidentiality-protected.
       UE uses the cached security context algorithms to protect the TAU Request message.
       ( reuse of keys allocated during attach procedure )
       ( 33.401 cl. 9.1.2 Idle mode procedures in E-UTRAN ) */
    /* Check that TRACKING AREA UPDATE REQUEST message is present and conforms
       with default message ( 36.508 Table 4.7.2-27: TRACKING AREA UPDATE REQUEST ) */
    v_NasInd := f_EUTRA_RRC_ConnEst_DefWithNas ( p_CellId, p_RRC_TI, v_EstablishmentCause,
                                                  cr_NAS_Indication(tsc_SHT_IntegrityProtected,
                                                                    cr_508_TAU_Request ( v_EpsUpdate_TypeValue,
                                                                                         v_KsiValue,
                                                                                         v_AdditionalUpdateType)));
    v_EPS_ContextStatus := v_NasInd.Pdu.Msg.tRACKING_AREA_UPDATE_REQUEST.epsBearerContextStatus; // Send this back in the Accept
    // UE has now establish SRB1 acc. to 36.331 cl. 5.3.3.4 and entered RRC_CONNECTED state
    
    /* Step 4: Transmit TRACKING AREA UPDATE ACCEPT message */
    /* In case MME has the cached security context it verifies the TAU Request message
       and replies with TAU Accept message protected with the cached security context
       ( 33.401 cl. 9.1.2 Idle mode procedures in E-UTRAN ) */
    SRB.send ( cas_SRB1_NasPdu_REQ ( p_CellId,
                                     cs_TimingInfo_Now,
                                     cs_NAS_Request ( tsc_SHT_IntegrityProtected_Ciphered,
                                                      cs_508_TAU_Accept ( v_EpsUpdate_TypeValue,
                                                                          f_GutiParameters2MobileIdentity ('50'O, v_GutiParams ),
                                                                          v_TaiList,
                                                                          v_EPS_ContextStatus,
                                                                          v_LAI,
                                                                          v_MSId,
                                                                          f_GetAdditionalUpdateResult(v_NasInd.Pdu.Msg.tRACKING_AREA_UPDATE_REQUEST.addUpdateType)))));
    
    /* Step 5: Receive TRACKING AREA UPDATE COMPLETE */
    /* According to 24.301 cl: 5.5.3.2.4:
       If the TRACKING AREA UPDATE ACCEPT message contained a GUTI,
       the UE shall return a TRACKING AREA UPDATE COMPLETE message to
       the MME to acknowledge the received GUTI */
    SRB.receive ( car_SRB1_NasPdu_IND ( p_CellId,
                                        cr_NAS_Indication ( tsc_SHT_IntegrityProtected_Ciphered,
                                                            cr_508_TAU_Complete ) ) );
  }

  /*
   * @desc      This procedure aims at checking whether the UE is camping on a new E-UTRAN cell with different TAI of a test case or not.
   *            The procedure is similar as the one defined in 36.508 cl. 6.4.2.7 table 6.4.2.7-1 with the exception
   *            that the parameterised list of PLMNs are indicated to UE as Equivalent PLMN in the Tracking Area Update Accept message
   * @param     p_CellId
   * @param     p_RRC_TI
   * @param     p_EPLMNlist
   * @param     p_ForcedAttach      (default value: NORMAL)
   * @status
   */

  function f_EUTRA_TrackingAreaUpdate_WithEplmn ( CellId_Type                p_CellId,
                                                  RRC_TransactionIdentifier  p_RRC_TI,
                                                  template (value) PLMN_List p_EPLMNlist,
                                                  EUTRA_ATTACH_Type p_ForcedAttach := NORMAL ) runs on EUTRA_PTC {

    var NAS_MSG_Indication_Type v_NasInd;
    var ReleaseCause v_ReleaseCause := other;
    var NAS_KsiValue v_KsiValue := f_EUTRA_SecurityKSIasme_Get ( );
    var GutiParameters_Type v_GutiParams:= f_EUTRA_CellInfo_GetGuti ( p_CellId );
    var NAS_PlmnId v_PLMN := f_Asn2Nas_PlmnId ( v_GutiParams.PLMN_Identity );
    var B3_Type v_EpsUpdate_TypeValue := f_GetEPSTAUType ( );
    var TrackingAreaCode v_Tac := f_EUTRA_CellInfo_GetTAC ( p_CellId );
    var NAS_Lac v_LAC := f_EUTRA_CellInfo_GetLocationAreaCode ( p_CellId );
    var EPS_BearerContextStatus v_EPS_ContextStatus;
    var template (omit) LocAreaId v_LAI := f_GetLAI ( v_PLMN, v_LAC );
    var template (omit) MobileIdentity v_MSId := f_GetMSId ( p_ForcedAttach );
    var template (value) TrackingAreaIdList v_TaiList := cds_TAIListNonConsecutive_tlv ( v_PLMN, { bit2oct( v_Tac ) } );
    var template AdditionalUpdateType v_AdditionalUpdateType := f_GetAdditionalUpdateType ();

    //Step 1 - 3: RRC Connection Establishment with TAU Request message
    //* The TAU Request shall be integrity-protected, but not confidentiality-protected.
    //* UE uses the cached security context algorithms to protect the TAU Request message.
    //* ( reuse of keys allocated during attach procedure )
    //* ( 33.401 cl. 9.1.2 Idle mode procedures in E-UTRAN )
    //* Check that TRACKING AREA UPDATE REQUEST message is present and conforms
    //* with default message ( 36.508 Table 4.7.2-27: TRACKING AREA UPDATE REQUEST )
    v_NasInd := f_EUTRA_RRC_ConnEst_DefWithNas ( p_CellId,
                                                 p_RRC_TI,
                                                 cr_EstablishmentCause_MoSignalling,
                                                 cr_NAS_Indication( tsc_SHT_IntegrityProtected,
                                                                    cr_508_TAU_Request ( v_EpsUpdate_TypeValue,
                                                                                         v_KsiValue,
                                                                                         v_AdditionalUpdateType ) ) );

    v_EPS_ContextStatus := v_NasInd.Pdu.Msg.tRACKING_AREA_UPDATE_REQUEST.epsBearerContextStatus; // Send this back in the Accept

    // UE has now establish SRB1 acc. to 36.331 cl. 5.3.3.4 and entered RRC_CONNECTED state

    //Step 4: Transmit TRACKING AREA UPDATE ACCEPT message with Equivalent PLMN list
    //* In case MME has the cached security context it verifies the TAU Request message
    //* and replies with TAU Accept message protected with the cached security context
    //* ( 33.401 cl. 9.1.2 Idle mode procedures in E-UTRAN )
    SRB.send ( cas_SRB1_NasPdu_REQ ( p_CellId,
                                     cs_TimingInfo_Now,
                                     cs_NAS_Request ( tsc_SHT_IntegrityProtected_Ciphered,
                                                      cds_TAU_Accept_EPLMN ( v_EpsUpdate_TypeValue,
                                                                             f_GutiParameters2MobileIdentity ( tsc_IEI_Guti, v_GutiParams ),
                                                                             v_TaiList,
                                                                             v_EPS_ContextStatus,
                                                                             v_LAI,
                                                                             v_MSId,
                                                                             f_GetAdditionalUpdateResult(v_NasInd.Pdu.Msg.tRACKING_AREA_UPDATE_REQUEST.addUpdateType),
                                                                             p_EPLMNlist   ) ) ) );

    //Step 5: Receive TRACKING AREA UPDATE COMPLETE
    //* According to 24.301 cl: 5.5.3.2.4:
    //* If the TRACKING AREA UPDATE ACCEPT message contained a GUTI, the UE shall return a
    //* TRACKING AREA UPDATE COMPLETE message to the MME to acknowledge the received GUTI
    SRB.receive ( car_SRB1_NasPdu_IND ( p_CellId,
                                        cr_NAS_Indication ( tsc_SHT_IntegrityProtected_Ciphered, cr_508_TAU_Complete ) ) );

    //* @verdict pass UE transmits a TRACKING AREA UPDATE COMPLETE
    f_EUTRA_PreliminaryPass(__FILE__, __LINE__, "UE transmits a TRACKING AREA UPDATE COMPLETE");

    //Step 6: Release RRC connection
    f_EUTRA_RRC_ConnectionRelease ( p_CellId, p_RRC_TI, v_ReleaseCause );
  }


  /*
   * @desc      UE Registration acc. to 36.508 cl. 4.5.2 with the exception that a Equivalent PLMN list is given to UE in Attach Accept messages.
   *            Function to be used in test case preamble when Equivalent PLMN is listed.
   * @param     p_CellId
   * @param     p_State - Wished UE state after procedure
   * @param     p_EPLMNlist - the listed Equivalent PLMNs to be sent to UE in Attach Accept message
   * @status
   */
  function f_EUTRA_IdleUpdated_WithEplmn ( CellId_Type                p_CellId,
                                           IDLEUPDATED_Type           p_Type,
                                           template (value) PLMN_List p_EPLMNlist,
                                           EUTRA_ATTACH_Type          p_ForcedAttach := NORMAL ) runs on EUTRA_PTC {

    var HalfOctet_Type v_EpsBearerId := tsc_EpsDefaultBearerId;
    var RRC_TransactionIdentifier v_RRC_TI := tsc_RRC_TI_Def;
    var ProcedureTransactionIdentifier v_EPS_TI := '00'O;
    var ReleaseCause v_ReleaseCause := other;
    var NAS_AttDetValue_Type v_AttachType := f_GetEAttachType ();
    var B3_Type v_PDNType := f_GetPdnType ( );
    var NAS_MSG_Indication_Type v_NasInd;
    var NAS_UL_Message_Type v_PdnConnectivityRequest;
    var template (present) SecurityHeaderType v_AttReqSecurityHeader;
    var template (present) SecurityHeaderType v_ExpectedSecurityHeader;
    var GutiParameters_Type v_GutiParams := f_EUTRA_CellInfo_GetGuti ( p_CellId );
    var NAS_Lac v_LAC := f_EUTRA_CellInfo_GetLocationAreaCode ( p_CellId );
    var NAS_PlmnId v_PLMN := f_Asn2Nas_PlmnId ( v_GutiParams.PLMN_Identity );
    var template (omit) LocAreaId v_LAI := f_GetLAI ( v_PLMN, v_LAC );
    var template (omit) MobileIdentity v_MSId := f_GetMSId ( p_ForcedAttach );
    var template (omit) ESM_Cause v_ESM_Cause := omit; // @sic R5-104703 sic@
    var NasCount_Type v_NasCountUL;
    var EUTRA_SecurityParams_Type v_AuthParams := f_EUTRA_Security_Get ( );
    var template (omit) AccessPointName v_APN := omit;
    var template (omit) ProtocolConfigOptions v_Pco := omit;
    var template (value) MobileIdentity v_Guti;
    var boolean v_IPallocationViaNasFlag;
    var template (value) PDN_Address v_PDN_Address;
    var TrackingAreaCode v_TAC := f_EUTRA_CellInfo_GetTAC ( p_CellId );
    var template AdditionalUpdateType v_AdditionalUpdateType := f_GetAdditionalUpdateType ();

    if (p_Type == PREAMBLE)
      {
        v_AttReqSecurityHeader := ( tsc_SHT_NoSecurityProtection, tsc_SHT_IntegrityProtected );
      }
    else
      {
        v_AttReqSecurityHeader := tsc_SHT_NoSecurityProtection;
      }

    //Step 2-4: Receive RRC Connection Setup Complete with Attach Request and piggybacked Pdn Connectivity Request
    v_NasInd := f_EUTRA_RRC_ConnEst_DefWithNas ( p_CellId,
                                                  v_RRC_TI,
                                                  cr_EstablishmentCause_Any,
                                                  cr_NAS_IndicationWithPiggybacking ( v_AttReqSecurityHeader,
                                                                                      cr_508_ATTACH_REQUEST ( v_AttachType, v_AdditionalUpdateType ),
                                                                                      cr_508_PDN_CONNECTIVITY_REQUEST ( tsc_PdnRequest_InitialAttach, v_PDNType ) ) );

    // Set UE network capabilities as sent by the UE to be used later (see TS 24.301 clause 5.4.3.3)
    v_AuthParams.NAS_SecurityCap := f_EUTRA_FillNAS_SecurityCapability(v_NasInd.Pdu.Msg.aTTACH_REQUEST);  // @sic R5s100135 sic@

    f_EUTRA_Security_Set(v_AuthParams);

    if (v_NasInd.SecurityProtection.Status == tsc_SHT_NoSecurityProtection) // @sic R5s090210, R5s090373 sic@
    {
      v_ExpectedSecurityHeader := tsc_SHT_NoSecurityProtection;
    } else {
      v_ExpectedSecurityHeader := (tsc_SHT_NoSecurityProtection, tsc_SHT_IntegrityProtected);
    }

    v_PdnConnectivityRequest := v_NasInd.Pdu.PiggybackedPduList[0].Msg;
    v_EPS_TI := v_PdnConnectivityRequest.pDN_CONNECTIVITY_REQUEST.procedureTransactionIdentifier; // Use this value in SS responses
    // Get the PCO to be used later (TS 36.508 v.8.2.2 Table 4.7.3-6)
    if (ispresent( v_PdnConnectivityRequest.pDN_CONNECTIVITY_REQUEST.protocolConfigurationOptions)) {
      v_Pco := v_PdnConnectivityRequest.pDN_CONNECTIVITY_REQUEST.protocolConfigurationOptions;
    }
    //Step 5-6: Authentication
    v_AuthParams := f_EUTRA_NAS_Authentication ( p_CellId,
                                                 tsc_SRB1,
                                                 v_AuthParams,
                                                 tsc_SHT_NoSecurityProtection,
                                                 v_ExpectedSecurityHeader,       // @sic R5s090210 sic@
                                                 v_PLMN);                        // AUTHENTICATION REQUEST & RESPONSE

    //Step 7-8: NAS Security
    v_NasCountUL := f_EUTRA_NAS_ActivateSecurity ( p_CellId,v_AuthParams );   // NAS SECURITY COMMAND & COMPLETE

    //Step 9a1 & 2: ESM information optionally transferred
    if (f_CheckEsmInfoTransferFlag(v_PdnConnectivityRequest.pDN_CONNECTIVITY_REQUEST)) {
      v_APN := f_ESM_InformationTransfer_GetAPN (p_CellId, v_EPS_TI);
    }

    //Step 10-11:  RRC Security Mode procedures
    v_AuthParams := f_EUTRA_RRC_ActivateSecurity( p_CellId, v_AuthParams, v_NasCountUL ); // RRC SECURITY COMMAND & COMPLETE
    f_EUTRA_Security_Set ( v_AuthParams );//Saving security parameters

    //Step 12-13: UE Capability check
    f_EUTRA_Capability ( p_CellId, v_RRC_TI );// This enquires for the eutra capability but does not check the contents of the message received

    v_Guti := f_GutiParameters2MobileIdentity(tsc_IEI_Guti, f_EUTRA_CellInfo_GetGuti(p_CellId));
    v_IPallocationViaNasFlag :=  f_CheckPCOforIPallocationViaNas (v_Pco); // See TS 36.508 v.8.2.2 Table 4.7.3-6
    v_PDN_Address := f_GetPDNAddress (v_IPallocationViaNasFlag);

    // @sic R5-103858 sic@
    if ( pc_IPv6 and pc_IPv4){
     v_ESM_Cause := cs_ESM_Cause_tv('00110010'B); // PDN type IPv4 only allowed @sic R5-104703 sic@
    }
    
    //Step 14-15: Send RRCConnectionReconfiguration with Attach Accept message including list of Equivalent PLMNs and piggybacked ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST
    f_TxAttachAcceptWithEquivalentPLMNList ( p_CellId,
                                             v_EpsBearerId,
                                             v_RRC_TI,
                                             v_EPS_TI,
                                             v_AttachType,
                                             v_PDN_Address,
                                             v_Guti,
                                             cs_TAIListNonConsecutive_lv (v_PLMN, {bit2oct(v_TAC)}),
                                             v_LAI,
                                             v_MSId,
                                             v_ESM_Cause,
                                             v_APN,
                                             p_EPLMNlist,
                                             f_GetDefPCOforPCSCFAddress (v_Pco), // @sic R5-104703 sic@
                                             v_NasInd.Pdu.Msg.aTTACH_REQUEST.addUpdateType );

    //Step 16: Receive Attach Complete
    f_EUTRA_NAS_AttachComplete(p_CellId, v_EpsBearerId );

   //Step 17: Release RRC connection
    f_EUTRA_RRC_ConnectionRelease(p_CellId, v_RRC_TI, v_ReleaseCause);
  }

  /*
   * @desc      step 3 .. 17 of UE Registration acc. to 36.508 cl. 4.5.2
   * @param     p_CellId
   * @param     p_State
   * @param     p_ForcedAttach      (default value: NORMAL)
   * @status    APPROVED
   */
  function f_EUTRA_IdleUpdated_WithoutRRCConnReq ( CellId_Type            p_CellId,
                                                   IDLEUPDATED_STATE_Type p_State,
                                                   EUTRA_ATTACH_Type      p_ForcedAttach := NORMAL) runs on EUTRA_PTC
  {
    var RRC_TransactionIdentifier v_RRC_TI := tsc_RRC_TI_Def;
    var NAS_AttDetValue_Type v_AttachType :=f_GetEAttachType(); //@sic R5-103673 : Removed paramater sic@
    var B3_Type v_PDNType := f_GetPdnType();
    var NAS_MSG_Indication_Type v_NAS_Ind;
    var template (present) SecurityHeaderType v_AttReqSecurityHeader := tsc_SHT_IntegrityProtected;
    var SRB_COMMON_IND v_ReceivedAsp;
    //v_AdditionalUpdateType defined to follow TTCN3 v411 standard
    var template AdditionalUpdateType v_AdditionalUpdateType := f_GetAdditionalUpdateType (); //@sic R5-103681 sic@

    // send RRC Connection Setup on SRB0 (CCCH) and switch on UL grant assignments:
    f_EUTRA_RRC_ConnectionSetup_Def (p_CellId, cs_TimingInfo_Now, v_RRC_TI);


    // UE shall establish SRB1 acc. to 36.331 cl. 5.3.3.4 and 5.3.9
    // UE enters RRC_CONNECTED state
    // SRB1 is established: no ciphering, no integrity protection for NAS/RRC

    // receive RRC Connection Setup Complete with piggy-backed NAS message on SRB1 (DCCH):
    SRB.receive(car_SRB1_RrcNasPdu_IND(p_CellId,
                                       cr_508_RRCConnectionSetupComplete(v_RRC_TI, ?),
                                       cr_NAS_IndicationWithPiggybacking(v_AttReqSecurityHeader,
                                                                         cr_508_ATTACH_REQUEST(v_AttachType,
                                                                                               v_AdditionalUpdateType),//@sic R5-103681 sic@
                                                                         cr_508_PDN_CONNECTIVITY_REQUEST(tsc_PdnRequest_InitialAttach, v_PDNType))))
      -> value v_ReceivedAsp;
    v_NAS_Ind := v_ReceivedAsp.Signalling.Nas[0];

    f_EUTRA_IdleUpdated_Step5_17 (p_CellId, p_State, p_ForcedAttach, v_NAS_Ind);

  }
  
  function f_EUTRA_CheckNoAttachOn3Cells(CellId_Type p_CellIdA,
                                         CellId_Type p_CellIdB,
                                         CellId_Type p_CellIdC,
                                         float p_Wait,
                                         charstring p_StepNo := "") runs on EUTRA_PTC
  {
    var template (present) CellId_Type v_CellId := (p_CellIdA, p_CellIdB, p_CellIdC);
    timer t_Wait := f_EUTRA_SetTimerToleranceMin (p_CellIdA, p_Wait);
    fl_EUTRA_CheckNoAttach_Common(v_CellId, t_Wait, p_StepNo);
  }
}
