/******************************************************************************/
// @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-16 10:33:37 +0200 (Thu, 16 Sep 2010) $
// $Rev: 3918 $
/******************************************************************************/

module UTRAN_CommonFunctions {

  import from UTRAN_RRC_ASN1_Definitions language "ASN.1:1997" all;
  import from UTRAN_ASP_Definitions language "ASN.1:1997" all;
  import from UTRAN_TypeDefs all;
  import from UTRAN_CellInfo all;
  import from UTRAN_Component all;
  import from UTRAN_Templates all;
  import from UTRAN_ASN1_Templates all;
  import from UTRAN_RAB_Templates all;
  import from UTRAN_ConfigurationSteps all;
  import from UTRANGERAN_CommonFunctions all;
  import from UTRAN_Parameters all;
  import from NAS_24008TypeDefs all;
  import from NAS_24008Templates all;
  import from NAS_CommonTemplates all;
  import from NAS_AuxiliaryDefsAndFunctions all;
  import from Parameters all;
  import from CommonDefs all;
  import from CommonIratDefs all;
  import from UpperTesterFunctions all;

  /*
   * @desc      Function which sends the cell info for the UTRAN cell to the EUTRA PTC
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_Send_IR_SysInfoToEUTRA (UTRAN_CellId_Type p_CellId) runs on UTRAN_PTC
  {
    var template (value) CoOrd_UTRANSysInfo_Type v_Cell;
    var B1_Type v_Diversity := '0'B;
    var B1_Type v_Tstd := '0'B;
    var FrequencyInfo v_FreqInfo := f_UTRAN_CellInfo_GetFrequencyInfo(p_CellId);
    var UTRAN_CellInfo_Type_FDD v_FDDInfo;
    var UTRAN_CellInfo_Type_TDD v_TDDInfo;
    
    if (f_UTRAN_CellInfo_GetFDD_TDD(p_CellId) == UTRAN_FDD)
      {
        v_FDDInfo := f_UTRAN_CellInfo_GetFDDSpecific(p_CellId);
        v_Cell := {FDD := cs_CoOrdUTRANSysInfo_FDD (v_FreqInfo.modeSpecificInfo.fdd.uarfcn_DL,
                                                    v_FDDInfo.priScrmCode,
                                                    f_U_Asn2Nas_PlmnId(f_UTRAN_CellInfo_GetPLMNIdentity(p_CellId)),
                                                    f_UTRAN_GetCellIndentity(p_CellId))};
      }
    else // TDD
      {
        v_TDDInfo := f_UTRAN_CellInfo_GetTDDSpecific(p_CellId);
        if (v_TDDInfo.transmissionDiversityApplied == applied)
          {
            v_Diversity := '1'B;
          }
        if (v_TDDInfo.dwPCHInfo.tstd_Indicator == applied)
          {
            v_Tstd := '1'B;
          }
        v_Cell := {TDD := cs_CoOrdUTRANSysInfo_TDD (v_FreqInfo.modeSpecificInfo.tdd.uarfcn_Nt,
                                                    v_TDDInfo.cellParametersID,
                                                    v_Diversity,
                                                    v_Tstd,
                                                    f_U_Asn2Nas_PlmnId(f_UTRAN_CellInfo_GetPLMNIdentity(p_CellId)),
                                                    f_UTRAN_GetCellIndentity(p_CellId))};
      }
    
    f_SendIRATCoOrd(EUTRA, cms_IRAT_SysInfo(cs_CoOrdUTRAN_SysInfoSingleCell(v_Cell)));
  }
  
  /*
   * @desc      Configure and Activate (or deactivate) ciphering for all concerned RBs
   * @param     p_CellId
   * @status
   */
  function f_RRC_Security(UTRAN_CellId_Type p_CellId,
                          // KeyCiphering p_KC,
                          // IntegrityKey p_IK,
                          // GSM_CipheringKey p_GSM_ck,
                          boolean p_NewKey,
                          CN_DomainIdentity p_CN_Domain) runs on UTRAN_PTC {

    var RB_ConfigType v_CellConfig := f_UTRAN_CellInfo_GetConfigType(p_CellId);
    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();
    var boolean v_Int_ModifyFlag := false;   // True means that an Integrity Modification is being done at that stage.
    var template (value) RB_ActivationTimeInfoList v_RB_ActivationTimeInfoList;
    var CRLC_RRC_MessageSN_CNF v_CRLC_RRC_MessageSN_CNF;
    var RRC_SequenceNumber v_SN_RB0, v_SN_RB1, v_SN_RB2, v_SN_RB2_UL, v_SN_RB3, v_SN_RB4;
    var ActivationTime v_CipherActTime;  /* TTCN-2: tcv_CipherActTime is set in f_CMAC_CipherCfg_r6 but only if parameter p_CalcNewActTime is set
                                            and the cell configuration causes configuration of ciphering at the SS
                                            => in TTCN-3 we set CipherActTime and hand it over to f_CMAC_CipherCfg
                                            as well as to fl_StartSecurityUE */
    v_CipherActTime := f_UTRAN_CalculateActTime(f_CPHY_GetFrameNumber(p_CellId, tsc_DL_DPCH1));
    
    select (px_UTRAN_CipheringAlgorithm) {
      case (uea2) {
        v_SecurityInfo.dL_CipherMode := valueof(cs_CipheringModeCmdOn(uea2));
      } case (uea1) {
        v_SecurityInfo.dL_CipherMode := valueof(cs_CipheringModeCmdOn(uea1));
      } case (uea0) {
        v_SecurityInfo.dL_CipherMode := valueof(cs_CipheringModeCmdOn(uea0));
      }
    }
    
    //   if (v_SecurityInfo.cipheringOnOff) {
        
    if (p_CN_Domain == cs_domain) {v_SecurityInfo.cs_cipheringStarted := true;}
    else                          {v_SecurityInfo.ps_cipheringStarted := true;}
    
    /*    } else {
          v_SecurityInfo.cs_cipheringStarted := false;
          v_SecurityInfo.ps_cipheringStarted := false;
          }
    */
    v_SecurityInfo.recentSecureDomain := p_CN_Domain;
    if (v_SecurityInfo.integrityStarted) {     // Modify integrity
      
      v_CRLC_RRC_MessageSN_CNF := f_CRLC_RRC_MessageSN_Get(tsc_RB0);
      v_SN_RB0 := v_CRLC_RRC_MessageSN_CNF.count_I_LSB_DL;
      
      v_CRLC_RRC_MessageSN_CNF := f_CRLC_RRC_MessageSN_Get(tsc_RB1);
      v_SN_RB1 := v_CRLC_RRC_MessageSN_CNF.count_I_LSB_DL;
      
      v_CRLC_RRC_MessageSN_CNF := f_CRLC_RRC_MessageSN_Get(tsc_RB2);
      v_SN_RB2 := v_CRLC_RRC_MessageSN_CNF.count_I_LSB_DL;
      v_SN_RB2_UL := v_CRLC_RRC_MessageSN_CNF.count_I_LSB_UL;
      
      v_CRLC_RRC_MessageSN_CNF := f_CRLC_RRC_MessageSN_Get(tsc_RB3);
      v_SN_RB3 := v_CRLC_RRC_MessageSN_CNF.count_I_LSB_DL;
      
      v_CRLC_RRC_MessageSN_CNF := f_CRLC_RRC_MessageSN_Get(tsc_RB4);
      v_SN_RB4 := v_CRLC_RRC_MessageSN_CNF.count_I_LSB_DL;
      
      v_SecurityInfo.dL_Integrity := valueof(cs_IntegrityProtectModify_P(v_SN_RB0, v_SN_RB1, v_SN_RB2, v_SN_RB3,  v_SN_RB4, uia2));
      v_Int_ModifyFlag := true;
    } else {                                            // Start integrity
      v_SecurityInfo.integrityStarted := true;
      if (px_UTRAN_CipheringAlgorithm == uea2) {
          v_SecurityInfo.integrProtAlgCap := '0000000000000110'B; // uia2
          v_SecurityInfo.dL_Integrity := valueof(cs_IntegrityProtectStart(px_FRESH, uia2));
      } else {
          v_SecurityInfo.integrProtAlgCap := '0000000000000010'B; // uia1
          v_SecurityInfo.dL_Integrity := valueof(cs_IntegrityProtectStart(px_FRESH, uia1));
      }
      v_SecurityInfo.dl_IntegrityCheckInfo := valueof(cs_IntegrityCheckInfo0);
      v_Int_ModifyFlag := false;
    }
    
    if (p_NewKey == true) {
      //Authentication was done, reset HFN
      v_SecurityInfo.authKeys.HFN := '00000000000000000000'B;
      if (p_CN_Domain == cs_domain) {v_SecurityInfo.start_CS := '00000000000000000000'B;}
      else                          {v_SecurityInfo.start_PS := '00000000000000000000'B;}
    } else {
      if (p_CN_Domain == cs_domain) {v_SecurityInfo.authKeys.HFN := v_SecurityInfo.start_CS;}
      else                          {v_SecurityInfo.authKeys.HFN := v_SecurityInfo.start_PS;}
    }
    f_UTRAN_Security_Set(v_SecurityInfo);     // write back information
    
    // DownloadSecurityKey:
    f_SS_DownloadSecurityKey(p_CellId, p_CN_Domain);
    
    // ActivateSecurity_DL_SS:
    if (not v_Int_ModifyFlag) {        // If Start of Integrity: Set DL RRC_MSN to 0, else skip it.
      f_SetDL_RRC_MessageSN(p_CellId);
    }
    f_CRLC_IntegrityActivate(cas_CRLC_DL_IntegrityActivateReq(utran_CellDedicated,
                                                              v_SecurityInfo.recentSecureDomain,
                                                              v_SecurityInfo.dL_Integrity));
    
    if (((v_SecurityInfo.ps_cipheringStarted) and (v_SecurityInfo.recentSecureDomain == ps_domain)) or
        ((v_SecurityInfo.cs_cipheringStarted) and (v_SecurityInfo.recentSecureDomain == cs_domain))) {
      v_RB_ActivationTimeInfoList := f_ActivateCiphering_DL_SS (p_CellId, v_CipherActTime);
    }
    
    if (v_Int_ModifyFlag) {
      f_CRLC_IntegrityActivate(cas_CRLC_UL_IntegrityActivateReq(utran_CellDedicated,
                                                                v_SecurityInfo.recentSecureDomain,
                                                                cs_RB2_IntegrityProtActivationInfoList(v_SN_RB2_UL)));
    } else {
      f_CRLC_IntegrityActivate(cas_CRLC_UL_IntegrityActivateReq(utran_CellDedicated,
                                                                v_SecurityInfo.recentSecureDomain,
                                                                cs_RB2_IntegrityProtActivationInfoList(0)));
    }
    
    f_CRLC_ProhibitRLC_Ack(tsc_RB2, cas_CRLC_ProhibitRLC_Ack_REQ(utran_CellDedicated, tsc_RB2));
    
    // lt_StartSecurity_UE:
    v_SecurityInfo := fl_StartSecurityUE(v_CellConfig,
                                         v_SecurityInfo,
                                         v_RB_ActivationTimeInfoList,
                                         p_CN_Domain,
                                         v_CipherActTime);
    f_UTRAN_Security_Set(v_SecurityInfo);
    
    f_CRLC_ProhibitRLC_Ack(tsc_RB2, cas_CRLC_ContinueRLC_Ack_REQ(utran_CellDedicated, tsc_RB2));
    
    if (((v_SecurityInfo.ps_cipheringStarted) and (v_SecurityInfo.recentSecureDomain == ps_domain)) or
        ((v_SecurityInfo.cs_cipheringStarted) and (v_SecurityInfo.recentSecureDomain == cs_domain))) {
      f_CRLC_ResumeSecurity(p_CellId);
    }
  }

  /*
   * @desc      To download a new START value In the security Record
   * @param     p_Domain
   * @param     p_StartValue
   * @status
   */
  function f_SS_SecurityDownloadStart(CN_DomainIdentity p_Domain,
                                      START_Value       p_StartValue) runs on UTRAN_PTC
  {
    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();
    if (p_Domain == cs_domain) {
      v_SecurityInfo.start_CS := p_StartValue;
    } else if (p_Domain == ps_domain) {
      v_SecurityInfo.start_PS := p_StartValue;
    }
    f_UTRAN_Security_Set(v_SecurityInfo);
  }

  /*
   * @desc      To download all security keys to CMAC (for DCH cell configurations only) and U_CRLC.
   * @param     p_CellId
   * @param     p_Domain
   * @status
   */
  function f_SS_DownloadSecurityKey(UTRAN_CellId_Type p_CellId,
                                    CN_DomainIdentity p_Domain) runs on UTRAN_PTC {

    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();
    var RB_ConfigType v_CellConfig := f_UTRAN_CellInfo_GetConfigType(p_CellId);
    var B20_Type v_HFN := v_SecurityInfo.authKeys.HFN;
    var KeyCiphering v_KC;
    var IntegrityKey v_IK;
    //    var GSM_CipheringKey v_GSM_ck := v_SecurityInfo.authKeys.AuthKcGSM;
    
    if (p_Domain == cs_domain)
      {
        v_KC := v_SecurityInfo.authKeys.AuthCS.CKey;
        v_IK := v_SecurityInfo.authKeys.AuthCS.IKey;
      }
    else {
      v_KC := v_SecurityInfo.authKeys.AuthPS.CK;
      v_IK := v_SecurityInfo.authKeys.AuthPS.IK;
    }
    
    
    //    if (v_SecurityInfo.cipheringOnOff) {
    select (v_CellConfig) {
      case (cell_FACH_NoConn, cell_FACH, cell_FACH_NoDedicated) {
        // Cell FACH
        f_CRLC_SecurityMode_Config(p_Domain, v_HFN, v_KC, v_IK, omit);
      }
      case (cell_DCH_StandAloneSRB_NoConn,
            cell_DCH_StandAloneSRB,
            cell_DCH_64kPS_RAB_SRB,
            cell_DCH_E_HS,
            cell_E_HS) {
        // Cell DCH; no TM RAB
        f_CRLC_SecurityMode_Config(p_Domain, v_HFN, v_KC, v_IK, omit);
      }
      case (cell_DCH_Speech) {
        // cell DCH with TM RAB
        f_CRLC_SecurityMode_Config(p_Domain, v_HFN, v_KC, v_IK, omit);
        f_CMAC_SecurityMode_Config(p_Domain, v_HFN, v_KC, omit, omit);
      }
    }
    /*    } else {                        // not tcv_CellIndInfo.cipheringOnOff
          if ((v_CellConfig == cell_FACH_NoConn) or
          (v_CellConfig == cell_FACH) or
          (v_CellConfig == cell_FACH_NoDedicated)) {
          // Cell FACH
          f_CRLC_SecurityMode_Config(p_Domain, v_HFN, omit, v_IK, omit);
          
          } else if ((v_CellConfig == cell_DCH_StandAloneSRB_NoConn) or
          (v_CellConfig == cell_DCH_StandAloneSRB) or
          (v_CellConfig == cell_DCH_64kPS_RAB_SRB)) {
          // Cell DCH; no TM RAB
          f_CRLC_SecurityMode_Config(p_Domain, v_HFN, omit, v_IK, omit);
          
          } else if ((v_CellConfig == cell_DCH_Speech)) {
          // cell DCH with TM RAB
          f_CRLC_SecurityMode_Config(p_Domain, v_HFN, omit, v_IK, omit);
          }
          } */
  }

  /*
   * @desc      Send SecurityModeCommand and receive SecurityModeComplete and configure SS according to UE configuration
   * @param     p_CellConfig
   * @param     p_SecurityInfo
   * @param     p_RB_ActivationTimeInfoList
   * @param     p_CN_Domain
   * @param     p_CipherActTime
   * @return    UTRAN_SecurityInfo_Type
   * @status
   */
  function fl_StartSecurityUE(RB_ConfigType           p_CellConfig,
                              UTRAN_SecurityInfo_Type p_SecurityInfo,
                              template (value) RB_ActivationTimeInfoList p_RB_ActivationTimeInfoList,
                              CN_DomainIdentity p_CN_Domain,
                              ActivationTime    p_CipherActTime) runs on UTRAN_PTC return UTRAN_SecurityInfo_Type
  {
    var UTRAN_SecurityInfo_Type  v_SecurityInfo := p_SecurityInfo;
    var IntegrityProtActivationInfo v_IntegrityActInfo;
    var bitstring v_UE_SystemSpecificCap  := int2bit(f_InitSystemSpecificCap(),7);
    var U_RLC_AM_IND v_RLC_AM_DATA_IND;
    
    // ********** Send SecurityModeCommand:
    if (pc_GERAN) {
      //    if (v_SecurityInfo.cipheringOnOff) { // Ciphering ON and integrity ON
      if (((p_CellConfig== cell_DCH_Speech)) and (v_SecurityInfo.recentSecureDomain == cs_domain)) {
        // Ciphering on TM  RAB present, hence include Ciphering activation time
        // Ciphering for signalling RBs 1 to 4
        U_AM.send(cas_RLC_Data_Req_NoCnf ( utran_CellDedicated,
                                           tsc_RB2,
                                           cs_108_RRC_SecModeCmd(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                                 cs_RRC_SecModeCmdCiphInt(tsc_RRC_TI,
                                                                                          v_SecurityInfo.dL_CipherMode,
                                                                                          p_RB_ActivationTimeInfoList,
                                                                                          p_CipherActTime,
                                                                                          p_CN_Domain,
                                                                                          v_SecurityInfo.dL_Integrity,
                                                                                          v_SecurityInfo.cipheringAlgorithmCapability,
                                                                                          cs_UE_SysSpecCap(v_UE_SystemSpecificCap),
                                                                                          v_SecurityInfo.integrProtAlgCap))));
      } else {
        // Ciphering for signalling RBs 1 to 4
        U_AM.send(cas_RLC_Data_Req_NoCnf ( utran_CellDedicated,
                                           tsc_RB2,
                                           cs_108_RRC_SecModeCmd(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                                 cs_RRC_SecModeCmdCiphInt(tsc_RRC_TI,
                                                                                          v_SecurityInfo.dL_CipherMode,
                                                                                          p_RB_ActivationTimeInfoList,
                                                                                          omit,
                                                                                          p_CN_Domain,
                                                                                          v_SecurityInfo.dL_Integrity,
                                                                                          v_SecurityInfo.cipheringAlgorithmCapability,
                                                                                          cs_UE_SysSpecCap(v_UE_SystemSpecificCap),
                                                                                          v_SecurityInfo.integrProtAlgCap))));
      }
      /*     } else {                                     // Integrity ON and  ciphering OFF
             U_AM.send(cas_RLC_Data_Req_NoCnf ( utran_CellDedicated,
             tsc_RB2,
             cs_108_RRC_SecModeCmd(v_SecurityInfo.dl_IntegrityCheckInfo,
             cs_RRC_SecModeCmdInt(tsc_RRC_TI,
             p_CN_Domain,
             v_SecurityInfo.dL_Integrity,
             v_SecurityInfo.cipheringAlgorithmCapability,
             cs_UE_SysSpecCap(v_UE_SystemSpecificCap),
             v_SecurityInfo.integrProtAlgCap)))));
             } */
    } else {                                       // NOT pc_GERAN
      //      if (v_SecurityInfo.cipheringOnOff) {  // Ciphering ON and integrity ON
      if (((p_CellConfig== cell_DCH_Speech)) and (v_SecurityInfo.recentSecureDomain == cs_domain)) {
        // Ciphering on TM  RAB present, hence include Ciphering activation time
        // Ciphering for signalling RBs 1 to 4
        U_AM.send(cas_RLC_Data_Req_NoCnf ( utran_CellDedicated,
                                           tsc_RB2,
                                           cs_108_RRC_SecModeCmd(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                                 cs_RRC_SecModeCmdCiphInt(tsc_RRC_TI,
                                                                                          v_SecurityInfo.dL_CipherMode,
                                                                                          p_RB_ActivationTimeInfoList,
                                                                                          p_CipherActTime,
                                                                                          p_CN_Domain,
                                                                                          v_SecurityInfo.dL_Integrity,
                                                                                          v_SecurityInfo.cipheringAlgorithmCapability,
                                                                                          omit,
                                                                                          v_SecurityInfo.integrProtAlgCap))));
      } else {
        // Ciphering for signalling RBs 1 to 4
        U_AM.send(cas_RLC_Data_Req_NoCnf ( utran_CellDedicated,
                                           tsc_RB2,
                                           cs_108_RRC_SecModeCmd(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                                 cs_RRC_SecModeCmdCiphInt(tsc_RRC_TI,
                                                                                          v_SecurityInfo.dL_CipherMode,
                                                                                          p_RB_ActivationTimeInfoList,
                                                                                          omit,
                                                                                          p_CN_Domain,
                                                                                          v_SecurityInfo.dL_Integrity,
                                                                                          v_SecurityInfo.cipheringAlgorithmCapability,
                                                                                          omit,
                                                                                          v_SecurityInfo.integrProtAlgCap))));
      }
      /*     } else {                                     // Integrity ON and  ciphering OFF
             U_AM.send(cas_RLC_Data_Req_NoCnf ( utran_CellDedicated,
             tsc_RB2,
             cs_108_RRC_SecModeCmd(v_SecurityInfo.dl_IntegrityCheckInfo,
             cs_RRC_SecModeCmdInt(tsc_RRC_TI,
             p_CN_Domain,
             v_SecurityInfo.dL_Integrity,
             v_SecurityInfo.cipheringAlgorithmCapability,
             omit,
             v_SecurityInfo.integrProtAlgCap)))));
             } */
    }
    
    // ********** Receive SecurityModeComplete:
    
    alt {
      //   [v_SecurityInfo.cipheringOnOff]            // Ciphering and Integrity
      [] U_AM.receive ( car_RLC_Data_Ind ( utran_CellDedicated,
                                           tsc_RB2,
                                           cr_108_RRC_SecModeCmpl(tsc_RRC_TI, ?))) -> value v_RLC_AM_DATA_IND {
        // UL ciphering information is present
        v_SecurityInfo.uL_Integrity := v_RLC_AM_DATA_IND.data.aM_message.uL_DCCH_Message.message_.securityModeComplete.ul_IntegProtActivationInfo;
        v_SecurityInfo.uL_CipherMode := v_RLC_AM_DATA_IND.data.aM_message.uL_DCCH_Message.message_.securityModeComplete.rb_UL_CiphActivationTimeInfo;
        v_IntegrityActInfo := v_SecurityInfo.uL_Integrity;
        
        f_CRLC_CipheringActivate(cas_CRLC_UL_CipherActReq(utran_CellDedicated,
                                                          v_SecurityInfo.recentSecureDomain,
                                                          p_RB_ActivationTimeInfoList,
                                                          notInc));
        
        f_CRLC_IntegrityActivate(cas_CRLC_UL_IntegrityActivateReq(
                                                                  utran_CellDedicated,
                                                                  v_SecurityInfo.recentSecureDomain,
                                                                  cs_RestRB_IntegrityProtActivationInfoList(v_IntegrityActInfo.rrc_MessageSequenceNumberList[0],
                                                                                                            v_IntegrityActInfo.rrc_MessageSequenceNumberList[1],
                                                                                                            v_IntegrityActInfo.rrc_MessageSequenceNumberList[3],
                                                                                                            v_IntegrityActInfo.rrc_MessageSequenceNumberList[4])));
      }
      /*   [not v_SecurityInfo.cipheringOnOff]      // Ciphering and Integrity
           U_AM.receive ( car_RLC_Data_Ind ( utran_CellDedicated,
           tsc_RB2,
           cr_108_RRC_SecModeCmpl(tsc_RRC_TI, omit))) -> value v_RLC_AM_DATA_IND {
           v_SecurityInfo.uL_Integrity := v_RLC_AM_DATA_IND.data.aM_message.uL_DCCH_Message.message_.securityModeComplete.ul_IntegProtActivationInfo;
           v_IntegrityActInfo := v_SecurityInfo.uL_Integrity;
           
           f_CRLC_IntegrityActivate(cas_CRLC_UL_IntegrityActivateReq(
           utran_CellDedicated,
           v_SecurityInfo.recentSecureDomain,
           cs_RestRB_IntegrityProtActivationInfoList(v_IntegrityActInfo.rrc_MessageSequenceNumberList[0],
           v_IntegrityActInfo.rrc_MessageSequenceNumberList[1],
           v_IntegrityActInfo.rrc_MessageSequenceNumberList[3],
           v_IntegrityActInfo.rrc_MessageSequenceNumberList[4])));
           } */
      [] U_AM.receive ( car_RLC_Data_Ind( utran_CellDedicated,
                                          tsc_RB2,
                                          cr_108_SecModeFail(tsc_RRC_TI, ?))) {
        f_UTRAN_SetVerdictFailOrInconc (__FILE__, __LINE__, "Security Failed");
      }
    }
    return v_SecurityInfo;
  }

  /*
   * @desc      If UE supports GSM, this step initialises tcv_UE_SystemSpecificCap based on PICS
   * @status
   */
  function f_InitSystemSpecificCap() return integer
  {
    var integer v_UE_SystemSpecificCap := 0;
    
    if (pc_GERAN) {
      v_UE_SystemSpecificCap := v_UE_SystemSpecificCap + 1; //A5_1 always supported
      v_UE_SystemSpecificCap := v_UE_SystemSpecificCap + 4; // A5_3 always Supported
    }
    return v_UE_SystemSpecificCap;
  }

  /*
   * @desc      Send Attach Accept and receive Attach Complete
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_AttachAccept(UTRAN_CellId_Type p_CellId) runs on UTRAN_PTC
  {
    var octetstring v_PLMN := f_U_Asn2Nas_PlmnId(f_UTRAN_CellInfo_GetPLMNIdentity(p_CellId));
    var octetstring v_LAC := f_UTRAN_CellInfo_GetLAC(p_CellId);
    var octetstring v_RAC := f_UTRAN_CellInfo_GetRAC(p_CellId);
    
    //    if ((px_UE_OpModeDef == opModeA) and (v_NMO == tsc_NMO_I)) {
    U_Dc.send(cs_PS_DataReq(utran_CellDedicated,                // ATTACH ACCEPT for combined CS/PS
                            tsc_RB3,
                            cs_U_AttachAcc(cs_GMM_AttachResult('011'B),
                                           cs_RAI(omit,
                                                  cs_LAI(omit, v_PLMN, v_LAC),
                                                  v_RAC),
                                           cs_PTMSI_Signature(px_PTMSI_SigDef),
                                           cs_MobileIdTMSIorPTMSI('18'O, px_PTMSI_Def))));
    /* Only implementing NMO I with CS/PS for now
       } else {
       U_Dc.send(cs_PS_DataReq(utran_CellDedicated,                // ATTACH ACCEPT for combined PS only
       tsc_RB3,
       cs_U_AttachAcc(cs_GMM_AttachResult('011'B),
       cs_RAI(omit, v_PLMN,
       v_LAC,
       v_RAC)),
       c_PTMSI_Signature(px_PTMSI_SigDef),
       c_MobileIdPTMSI(px_PTMSI_Def),
       omit,
       omit));
       } */
    U_Dc.receive(car_PS_UplinkDirectTransfer(utran_CellDedicated,
                                             tsc_RB3,
                                             cr_U_AttachComplete));
  }

  /*
   * @desc      From BenchMark project and it used to be LOCAL_GMMOnly_IdleUpdated
   *            and start with     f_UT_SwitchOnUE() followed by Trigger Attach
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_GMMOnly_Attach(UTRAN_CellId_Type p_CellId) runs on UTRAN_PTC {

    var START_Value v_START_Value := '00000000000000000000'B;
    var RB_ConfigType v_CellConfig;
    var RRC_DATA_IND v_RRC_DataInd;
    var boolean v_NewKeyFlag := true;
    
    /*    if (not pc_AutomaticAttachSwitchON) {   // UE does not automatically attach at switch on
          f_NAS_Delay(tsc_TWaitSysInfo);
          f_AT_TriggerGMM_Attach_Common(Ut);
          } else {
          // Do nothing: UE will automatically attempt PS attach
          }
    */
    f_UTRAN_RRC_ConnEst(p_CellId, est_Reg, registration); // Establish RRC connection
    alt {
      [] U_Dc.receive(car_PS_InitDirectTransfer(utran_CellDedicated, tsc_RB3, cr_U_AttachReq(cr_AttachTypeAny,
                                                                                             cr_MobileIdAny(omit),
                                                                                             cr_RAI_Any(omit),
                                                                                             ?) ))
        -> value v_RRC_DataInd {
        v_START_Value := v_RRC_DataInd.ttcn_start;
        f_SS_SecurityDownloadStart(ps_domain, v_START_Value);
      }
    }
    f_GMM_Authentication();
    f_RRC_Security(p_CellId,                        // SECURITY MODE COMMAND, SECURITY MODE COMPLETE
                   v_NewKeyFlag,
                   ps_domain);
    
    f_UTRAN_AttachAccept(p_CellId);       // ATTACH ACCEPT, ATTACH COMPLETE
    
    v_CellConfig := f_UTRAN_CellInfo_GetConfigType(p_CellId);  // Updated earlier in RRC Conn Est
    select (v_CellConfig) {
      case (cell_FACH) {
        f_UTRAN_RRC_ConnRel(p_CellId, cell_Fach_Dcch);
      }
      case else {
        f_UTRAN_RRC_ConnRel(p_CellId, cell_Dch);
      }
    }
  }

  /*
   * @desc      Sends RRC CONNECTION SETUP COMPLETE and receives RRC CONNECTION SETUP COMPLETE
   * @param     p_CellId
   * @param     p_InitialUE_Id
   * @status
   */
  function f_UTRAN_RRC_ConnEst_WithoutRRCConnectionReq ( UTRAN_CellId_Type  p_CellId,
                                                         InitialUE_Identity p_InitialUE_Id ) runs on UTRAN_PTC {
  
    var RB_ConfigType v_CellConfig := f_UTRAN_CellInfo_GetConfigType (p_CellId);
    var UTRAN_FDD_TDD v_FDD_TDD_Mode := f_UTRAN_CellInfo_GetFDD_TDD (p_CellId);
    var boolean v_UtranIsFDD;
    var UTRAN_CellInfo_Type_FDD v_CellInfoFDD;
    var UTRAN_CellInfo_Type_TDD v_CellInfoTDD;
    var U_RNTI v_U_RNTI := f_UTRAN_CellInfo_GetU_RNTI(p_CellId);
    var C_RNTI v_C_RNTI := f_UTRAN_CellInfo_GetC_RNTI(p_CellId);
    
    //This function assumes that DCH is already configured and is ready for an RRC connection to be established
    
    select  (v_FDD_TDD_Mode) {
      case (UTRAN_FDD) {
        v_CellInfoFDD := f_UTRAN_CellInfo_GetFDDSpecific(p_CellId);
        v_UtranIsFDD := true;
      }
      case (UTRAN_TDD) {
        v_CellInfoTDD := f_UTRAN_CellInfo_GetTDDSpecific(p_CellId);
        v_UtranIsFDD := false;
      }
      case else {
        FatalError(__FILE__, __LINE__, "Cell is neither FDD nor TDD");
      }
    }
  
    select (v_CellConfig) {
      case (cell_FACH_NoConn) {
        if (v_UtranIsFDD) {
          U_UM.send(cas_RRC_ConnSetup(p_CellId,
                                      tsc_RB0,
                                      cs_108_RRC_ConnSetupFACH_r8_FDD(p_InitialUE_Id,
                                                                      tsc_RRC_TI,
                                                                      v_U_RNTI,
                                                                      v_C_RNTI)));
        } else {
          U_UM.send(cas_RRC_ConnSetup(p_CellId,
                                      tsc_RB0,
                                      cs_108_RRC_ConnSetupFACH_r8_TDD(p_InitialUE_Id,
                                                                      tsc_RRC_TI,
                                                                      v_U_RNTI,
                                                                      v_C_RNTI)));
        }
        f_UTRAN_CellInfo_SetConfigType(p_CellId, cell_FACH);
      }
      case (cell_DCH_StandAloneSRB_NoConn) {
        if (v_UtranIsFDD) {
          U_UM.send(cas_RRC_ConnSetup(p_CellId,
                                      tsc_RB0,
                                      cs_108_RRC_ConnSetupDCH_r8_FDD(p_InitialUE_Id,
                                                                     tsc_RRC_TI,
                                                                     v_CellInfoFDD.priScrmCode,
                                                                     v_U_RNTI,
                                                                     v_CellInfoFDD.uL_ScramblingCode)));
        } else {
          U_UM.send(cas_RRC_ConnSetup(p_CellId,
                                      tsc_RB0,
                                      cs_108_RRC_ConnSetupDCH_r8_TDD(p_InitialUE_Id,
                                                                     tsc_RRC_TI,
                                                                     v_U_RNTI,
                                                                     v_CellInfoTDD.cellParametersID)));
          
        }
        f_UTRAN_CellInfo_SetConfigType(p_CellId, cell_DCH_StandAloneSRB);
      }
      case else {
        FatalError(__FILE__, __LINE__, "invalid configuration");
      }
    }
    f_UTRAN_RRC_ReceiveConnSetupCmpl(p_CellId);
  }

  /*
   * @desc      The generic Step to establish RRC Connection and bring UE to CELL_FACH or CELL_DCH state.
   *            In this Step , 5 Signalling Radio Bearers with 3.4kbps DL & UL is setup (RB#0, 1, 2, 3,4).
   * @param     p_CellId
   * @param     p_MO_Reg
   * @param     p_EstCause
   * @status
   */
  function f_UTRAN_RRC_ConnEst(UTRAN_CellId_Type p_CellId,
                               RegOr_MO p_MO_Reg,
                               template (present) EstablishmentCause p_EstCause) runs on UTRAN_PTC
  {
    var InitialUE_Identity v_InitialUE_Id;
    var template (present) EstablishmentCause v_EstCause;
    var RLC_TR_DATA_IND v_RLC_TR_DATA_IND;
    
    // ts_SS_PrepareCellRRC_ConnEst(p_CellId);
    // This function assumes that DCH is already configured and is ready for an RRC connection to be established
    
    select (p_MO_Reg) {
      case (est_Reg) {
        v_EstCause := registration;
      }
      case (est_MO, est_MT) {
        v_EstCause := p_EstCause;
      }
    }

    alt {
      [] U_TM.receive(car_RRC_ConnReq(p_CellId,
                                      tsc_RB0,
                                      cdr_RRC_ConnReq_r8OrLater(v_EstCause))) -> value v_RLC_TR_DATA_IND
        {
          v_InitialUE_Id := v_RLC_TR_DATA_IND.tM_message.uL_CCCH_Message.message_.rrcConnectionRequest.initialUE_Identity;
        }
    }
    f_UTRAN_RRC_ConnEst_WithoutRRCConnectionReq ( p_CellId, v_InitialUE_Id );
  }
  
  /*
   * @desc      To receive RRC CONNECTION SETUP COMPLETE  message and download SS security keys according to the received information element.
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_RRC_ReceiveConnSetupCmpl(UTRAN_CellId_Type p_CellId) runs on UTRAN_PTC
  {

    var RB_ConfigType v_CellConfig := f_UTRAN_CellInfo_GetConfigType(p_CellId);
    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();
    var RRCConnectionSetupComplete v_RRCConnectionSetupComplete;
    var U_RLC_AM_IND v_RLC_AM_DATA_IND;
    var STARTList v_STARTList;
    var integer v_DomainCnt;
    var boolean v_ConfigIsDCH;
    var integer I;
    
    select (v_CellConfig) {
      case (cell_DCH_StandAloneSRB_NoConn,
            cell_DCH_StandAloneSRB,
            cell_E_HS_StandAloneSRB) {
        v_ConfigIsDCH := true;
      }
      case (cell_FACH_NoConn,
            cell_FACH) {
        v_ConfigIsDCH := false;
      }
      case else {
        FatalError(__FILE__, __LINE__, "invalid configuration");
      }
    }
    
    alt {
      [] U_AM.receive ( car_RLC_Data_Ind ( utran_CellDedicated,
                                           tsc_RB2,
                                           cr_108_RRC_ConnSetupCmpl(tsc_RRC_TI, ?))) // TTCN2 checks all UE capabilities at this point
        -> value v_RLC_AM_DATA_IND
        {
          v_RRCConnectionSetupComplete := v_RLC_AM_DATA_IND.data.aM_message.uL_DCCH_Message.message_.rrcConnectionSetupComplete;
        }
      // swallow any excess ConnReq messages that haven't been processed yet
      [] U_TM.receive(car_RRC_ConnReq(?, tsc_RB0, cr_RRC_RrcConnReqAny))
        {
          repeat;
        }
    }
    // get start list
    v_STARTList := v_RRCConnectionSetupComplete.startList;
    
    if (v_ConfigIsDCH) {
      // store cipheringAlgorithmCap
      v_SecurityInfo.cipheringAlgorithmCapability := v_RRCConnectionSetupComplete.ue_RadioAccessCapability.securityCapability.cipheringAlgorithmCap;
    }
    v_DomainCnt := sizeof(v_STARTList);
    if ((v_DomainCnt > 0) and (v_DomainCnt <= 2)) {
      for (I:=0; I<v_DomainCnt; I:=I+1) {
        if (v_STARTList[I].cn_DomainIdentity == cs_domain) {
          v_SecurityInfo.start_CS := v_STARTList[I].start_Value;
        } else {
          v_SecurityInfo.start_PS := v_STARTList[I].start_Value;
        }
      }
    } else {
      FatalError(__FILE__, __LINE__, "invalid configuration");
    }
    f_UTRAN_Security_Set(v_SecurityInfo);
  }

  /*
   * @desc      To bring the UE from state CELL_DCH/ CELL_FACH to idle state by releasing the RRC connection
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_RRC_ConnRel(UTRAN_CellId_Type p_CellId,
                               RRC_Rel_Status    p_RRC_RelStatus) runs on UTRAN_PTC {

    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();
    var integer v_N308 := 2;     // Maximum number of retransmissions of the RRC CONNECTION RELEASE COMPLETE message.

    f_Delay(1.0);

    if (p_RRC_RelStatus == cell_Dch) {
      fl_RRC_ConnRel_DCH(v_SecurityInfo.dl_IntegrityCheckInfo, v_N308);
      
    } else if (p_RRC_RelStatus == cell_Fach_Dcch) {
      U_UM.send(cas_RRC_ConnRelDCCH(utran_CellDedicated,
                                    tsc_RB1,
                                    cs_108_RRC_ConnRelDCCH_r4(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                              tsc_RRC_TI,
                                                              omit)));
      U_AM.receive ( car_RLC_Data_Ind ( utran_CellDedicated,
                                        tsc_RB2,
                                        cr_108_RRC_ConnRelCmpl(tsc_RRC_TI)));
      f_UTRAN_PreliminaryPass(__FILE__, __LINE__, "");
      f_Delay(1.0);
      
    } else if (p_RRC_RelStatus == cell_Fach_Ccch) {
      U_UM.send(cas_RRC_ConnRelCCCH(p_CellId,
                                    tsc_RB0,
                                    cs_108_RRC_ConnRelCCCH_r5(cs_U_RNTI_Def, tsc_RRC_TI)));
    } else {
      FatalError(__FILE__, __LINE__, "invalid configuration");
    }

    //  TO DO - Implement DPCH re-configuration
    f_RestartCRLC_ForNextConnection(p_CellId);
    f_SS_ResetSecurityKey();
  }

  /*
   * @desc
   * @param     p_IntegrityCheckInfo
   * @param     p_N308
   * @status
   */
  function fl_RRC_ConnRel_DCH(IntegrityCheckInfo p_IntegrityCheckInfo,
                              integer            p_N308) runs on UTRAN_PTC
  {
    var integer v_K := 1;
    timer t_WaitForRrcConRel := f_UG_SetTimerToleranceMax (5.0);
    
    U_UM.send(cas_RRC_ConnRelDCCH(utran_CellDedicated,
                                  tsc_RB1,
                                  cs_108_RRC_ConnRelDCCH_r4(p_IntegrityCheckInfo,
                                                            tsc_RRC_TI,
                                                            p_N308)));
    
    U_UM.receive(car_RRC_ConnRelCmplUM(utran_CellDedicated,
                                       tsc_RB1,
                                       cr_108_RRC_ConnRelCmpl(tsc_RRC_TI)));
    f_UTRAN_PreliminaryPass(__FILE__, __LINE__, "");
    
    //UE sends RRC Connection Release Complete for N308 times
    do {
      t_WaitForRrcConRel.start;
      alt {
        [] t_WaitForRrcConRel.timeout {
          f_UTRAN_SetVerdictFailOrInconc(__FILE__, __LINE__, "Insufficient RRC Connection Release");
          v_K := p_N308 + 1;   // To stop the loop
        }
        [] U_UM.receive(car_RRC_ConnRelCmplUM(utran_CellDedicated,
                                              tsc_RB1,
                                              cr_108_RRC_ConnRelCmpl(tsc_RRC_TI))) {
          t_WaitForRrcConRel.stop;
          v_K := v_K + 1;
        }
      }
    } while (not (v_K == (p_N308 + 1)));
  }

  /*
   * @desc      Generate authentication paramters and run  the GMM Authentication procedure
   *            See 3GPP 24.008 / 4.7, 3GPP 33.102 / 6.3 and  3GPP 34.108 / 8 (for the computation of authentication paramters for Test USIM)
   *            See also the detailed description in test Step f_MM_Authentication, on which this test Step is based.
   * @status
   */
  function f_GMM_Authentication() runs on UTRAN_PTC
  {
    var UTRAN_SecurityInfo_Type v_SecurityInfo:= f_UTRAN_Security_Get();
    var Common_AuthenticationParams_Type v_Auth_Params := v_SecurityInfo.authKeys.AuthPS;
    var RRC_DATA_IND v_RRC_DataInd;
    var AUTHENTICATIONANDCIPHERINGRESPONSE v_AuthAndCipherResp;
    var B32_Type    v_AuthRES_High;
    var bitstring   v_AuthRES;

    v_Auth_Params := f_AuthenticationInit(v_Auth_Params);        // modified by f_AuthenticationInit
    v_SecurityInfo.authKeys.AuthPS := v_Auth_Params;
    
    // AUTHENTICATION AND CIPHERING REQUEST using relevant PS keys computed before:
    U_Dc.send(cs_PS_DataReq(utran_CellDedicated,
                            tsc_RB3,
                            cs_U_AuthAndCiphReq(cs_GMM_AuthRAND(px_eAuthRAND),
                                                cs_GMM_KeySeq(v_Auth_Params.KeySeq),
                                                cs_GMM_AUTN(v_Auth_Params.AUTN))));
    alt {
      // AUTHENTICATION AND CIPHERING RESPONSE including both Authentication Response paramters (RES and RES ext)
      [] U_Dc.receive(car_PS_UplinkDirectTransfer(utran_CellDedicated,
                                                  tsc_RB3,
                                                  cr_U_AuthAndCiphRsp(cr_AuthRspAny,
                                                                      cr_AuthCiphRspExtAny)))
        -> value v_RRC_DataInd {
        v_AuthAndCipherResp := v_RRC_DataInd.msg.authenticationAndCipheringResponse;
        v_AuthRES_High := v_AuthAndCipherResp.authRsp.rES;
        v_AuthRES := v_AuthRES_High & v_AuthAndCipherResp.authRspExt.rES;
        // Verify that the received Authentication Response parameters match expected response:
        if (v_AuthRES != substr(v_Auth_Params.XRES, 0, lengthof(v_AuthRES))) {
          f_UTRAN_SetVerdictFailOrInconc(__FILE__, __LINE__, "Authentication Failed");
          }
      }
      // AUTHENTICATION AND CIPHERING RESPONSE including only one Authentication Response paramters (RES):
      [] U_Dc.receive(car_PS_UplinkDirectTransfer(utran_CellDedicated,
                                                  tsc_RB3,
                                                  cr_U_AuthAndCiphRsp(cr_AuthRspAny,
                                                                      omit)))
        -> value v_RRC_DataInd {
        v_AuthAndCipherResp := v_RRC_DataInd.msg.authenticationAndCipheringResponse;
        v_AuthRES_High := v_AuthAndCipherResp.authRsp.rES;
        // Verify that the received Authentication Response parameters match expected response:
        if (v_AuthRES_High != substr(v_Auth_Params.XRES, 0, lengthof(v_AuthRES_High))) {
          f_UTRAN_SetVerdictFailOrInconc(__FILE__, __LINE__, "Authentication Failed");
          }
      }
      // AUTHENTICATION AND CIPHERING Failure, then stop execution by assigning INCONCLUSIVE verdict as this might be a USIM issue.
      [] U_Dc.receive(car_PS_UplinkDirectTransfer(utran_CellDedicated,
                                                  tsc_RB3,
                                                  cr_U_AuthAndCiphFailureAny)) {
        FatalError(__FILE__, __LINE__, "received AUTHENTICATION_AND_CIPHERING_FAILURE");
        }
    }
    f_UTRAN_Security_Set(v_SecurityInfo);
  }

  /*
   * @desc      Procedure to be used in the test case preamble when UE should be brought to state
   *            Registered, Idle Mode (state 2) on an UTRAN cell.
   * @status
   */
  function f_UTRAN_Preamble ( UTRAN_CellId_Type p_CellId ) runs on UTRAN_PTC
  {
    
    var UTRAN_SecurityInfo_Type v_SecurityInfo;
    var Common_AuthenticationParams_Type v_AuthCS;
    //  Switch cell power on
    f_UTRAN_SetCellPower (utran_Cell5, tsc_AttenuationServingCell);
    
    //  Switch on UE
    f_UT_SwitchOnUE (UT, false);
    
    //  Establish RRC Connection, perform Authentication, Security Mode procedure,
    //  Attach procedure and release RRC Connection
    f_UTRAN_GMMOnly_Attach ( p_CellId );
    
    // Now get the security parameters that have been updated
    v_SecurityInfo := f_UTRAN_Security_Get ();
    // AuthCS not the same structure as AuthPS
    v_AuthCS := v_SecurityInfo.authKeys.AuthPS;
    v_AuthCS.CK := v_SecurityInfo.authKeys.AuthCS.CKey;
    v_AuthCS.IK := v_SecurityInfo.authKeys.AuthCS.IKey;
    v_AuthCS.KeySeq := v_SecurityInfo.authKeys.AuthCS.CKeySeq;

    
    EUTRA.send (cms_IRAT_AuthInfo(v_SecurityInfo.authKeys.AuthPS,
                                  v_AuthCS,
                                   omit));  // may need to send this eventually

  }

   /* @desc      To be called after UTRA_Init, before the test case body for every test that doesn't start in UTRAN.
   *             This will wait until Preamble is finished on EUTRA and it has received the AuthParams
   *             These are then stored in SecurityInfo
   */
  function f_UTRAN_InterRAT_InitialiseAuthParams () runs on UTRAN_PTC
  {
    var IRAT_Coordination_MSG v_RxdMsg;
    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();

    EUTRA.receive (cmr_IRAT_AuthInfo) -> value v_RxdMsg;
    
    v_SecurityInfo.authKeys.AuthPS := v_RxdMsg.Authentication.AuthPS;
    // AuthCS not the same structure as AuthPS
    v_SecurityInfo.authKeys.AuthCS.CKey := v_RxdMsg.Authentication.AuthCS.CK;
    v_SecurityInfo.authKeys.AuthCS.IKey := v_RxdMsg.Authentication.AuthCS.IK;
    v_SecurityInfo.authKeys.AuthCS.CKeySeq := v_RxdMsg.Authentication.AuthCS.KeySeq;
    
    f_UTRAN_Security_Set (v_SecurityInfo);
  }

  /*
   * @desc      Procedure to be used as the pre-Preamble to set the PTMSI, PTMSI Sig and TMSI in the USIM
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_Pre_Preamble (UTRAN_CellId_Type p_CellId) runs on UTRAN_PTC
  {
    f_UTRAN_SetCellPower (p_CellId, tsc_AttenuationServingCell);
    f_UT_SwitchOnUE(UT, false);
    f_UTRAN_GMMOnly_Attach ( p_CellId );
    f_UTRA_SwitchPower_Off (p_CellId, U1_IDLE);
    f_UTRAN_SetCellPower (p_CellId, tsc_AttenuationCellOFF);

    // then tell EUTRA it can do it's preamble
    f_SendIRATCoOrd (EUTRA, cms_IRAT_Trigger);
    }
  
  /*
   * @desc      Deactivates the PDP Context and releases the RRC Connection
   * @param     p_CellId
   * @param     p_RRC_Rel_Status
   * @status
   */
  function f_UTRAN_DeeactivatePDP_ContextMT ( UTRAN_CellId_Type p_CellId,
                                              RRC_Rel_Status p_RRC_Rel_Status := cell_Dch ) runs on UTRAN_PTC return NAS_ATTACH_STATE_Type
  {
    var NAS_ATTACH_STATE_Type v_Nas_Attach_State := ATTACHED;
    var integer I := 0;
    timer t_T3395 := f_UG_SetTimerToleranceMax (30.0);  //Timer T3395, 24.008, section 6.1.3.4.2    PDP context deactivation initiated by the network
    timer t_T3390 := f_UG_SetTimerToleranceMax (8.0);   //Timer T3390, 24.008
    
    //Transmit Downlink Direct Transfer with Deactivate PDP Context Request message
    U_Dc.send ( cs_PS_DataReq ( p_CellId,
                                tsc_RB3,
                                cs_U_DeactPdpContextReqMt ) );
    
    do {
      t_T3395.start;
      alt {
        //Receive Uplink Direct Transfer with Deactivate PDP Context Accept message
        [] U_Dc.receive ( car_PS_UplinkDirectTransfer ( p_CellId,
                                                        tsc_RB3,
                                                        cr_U_DeactPdpContextAcpMo ) )
          {
            t_T3395.stop;
            I := 5;
          }
        [] t_T3395.timeout
          {
            I := I + 1;
            U_Dc.send ( cs_PS_DataReq ( p_CellId,
                                        tsc_RB3,
                                        cs_U_DeactPdpContextReqMt ) );
          }
      }
    } while ( I < 5 );
    
    //If UE does not auto attach after PDP deactivation allow UE to detach automatically
    if ( not pc_AutomaticAttachSwitchON ) {
      t_T3390.start;
      alt {
        //Receive Detach message
        [] U_Dc.receive ( car_PS_UplinkDirectTransfer ( p_CellId,
                                                        tsc_RB3,
                                                        cr_U_DetachRequest ( cr_DetachTypeOnSwitchOff,
                                                                             cdr_MobileIdTMSI_tlv(?),
                                                                             cr_PTMSI_SignatureAny ifpresent )) )
          {
            t_T3390.stop;
            //Send Detach Accept message
            U_Dc.send ( cs_PS_DataReq ( p_CellId,
                                        tsc_RB3,
                                        cs_U_DetachAcc ) );
            v_Nas_Attach_State := DETACHED;
          }
        [] t_T3390.timeout {//No detach message has been received. Which means UE is still attached?
          //Release RRC Connection
          f_UTRAN_RRC_ConnRel ( p_CellId, p_RRC_Rel_Status );
        }
      }
    }
    else {
      //Release RRC Connection
      f_UTRAN_RRC_ConnRel ( p_CellId, p_RRC_Rel_Status );
    }
    return v_Nas_Attach_State;
  }

  /*
   * @desc      This procedure is according to 36.523-3 cl. 10.1.5 CS fallback procedure
   * @param     p_CellId
   * @status
   */
  function f_UTRA_CS_Fallback ( UTRAN_CellId_Type p_CellId ) runs on UTRAN_PTC
  {

    var octetstring v_Nmo := f_UTRAN_CellInfo_GetNMO ( p_CellId );
    var UTRA_POSTAMBLE_CONDITIONS v_Utra_Postamble_Condition := fl_UTRA_SetPostambleCondition ( );

    alt {
      //Step 1a1: Receive CM Service Request
      [] U_Dc.receive ( car_InitDirectTransfer ( p_CellId,
                                                 tsc_RB3,
                                                 cr_U_ServReqAny_Common ( ? ) ) )//FFS - Cipher key sequence number IE: What key willl be available?
      {
        //Step 1a2: Send CM Service Reject with reject cause #32 (Service Option not supported)
        U_Dc.send ( cs_DataReq ( p_CellId,
                                 tsc_RB3,
                                 cs_U_CM_ServRej ( tsc_ServiceOptionNotSupported ) ) );
      }
      //Step 1b1: Receive Paging Response
      [] U_Dc.receive ( car_PS_InitDirectTransfer ( p_CellId,
                                                    tsc_RB3,
                                                    cr_U_PagRsp_Common ( ?,//FFS - KeySeq
                                                                         ? ) ) )//FFS - MobileIdentity
      {}//Do nothing
    }

    //Step 2-3: Send RRC Connection Release and receive RRC Connection Release Complete
    f_UTRAN_RRC_ConnRel ( p_CellId, cell_Dch );
    //FFS - maybe N308 can be passed in as parameter?

    //Step 4-6: RRC Connection Establishment
    f_UTRAN_RRC_ConnEst ( p_CellId, est_MO, ? );

    //Step 7a1-7a5: Routing Area Procedure for the following scenarios
    // - NMO1 and C3
    if (v_Nmo == tsc_NMO_I and v_Utra_Postamble_Condition == UTRA_C3) {
      f_UTRAN_GMM_RAU_MappedContext ( p_CellId );
    }
    //Step 7b1-7b5: Location Updating procedure for the scenario
    // - (NMO1 or NMO2) and C4
    else if (v_Utra_Postamble_Condition == UTRA_C4  ){
      f_UTRAN_LocationUpdate ( p_CellId );
    }
    //Step 7c1 - 7c10: Perform Routing Area procedure and Location Updating procedure for the scenario
    // - NMO2 and (C1 or C3)
    else if (v_Nmo == tsc_NMO_II and ((v_Utra_Postamble_Condition == UTRA_C1) or (v_Utra_Postamble_Condition==UTRA_C3))) {
      f_UTRA_Interleaved_RauLau ( p_CellId );
    }

    //Step 8-9: Send RRC Connection Release and receive RRC Connection Release Complete
    f_UTRAN_RRC_ConnRel ( p_CellId, cell_Dch );
    //FFS - maybe N308 can be passed in as parameter?
  }

  function f_UTRA_Interleaved_RauLau ( UTRAN_CellId_Type p_CellId ) runs on UTRAN_PTC
  {

    var RRC_DATA_IND v_RRC_DataInd_RAU, v_RRC_DataInd_LAU;
    var B3_Type v_UpdateType_Ra := '000'B;
    var octetstring v_PLMN := f_U_Asn2Nas_PlmnId ( f_UTRAN_CellInfo_GetPLMNIdentity ( p_CellId ) );
    var octetstring v_LAC := f_UTRAN_CellInfo_GetLAC ( p_CellId );
    var octetstring v_RAC := f_UTRAN_CellInfo_GetRAC ( p_CellId );
    var START_Value v_RAU_START_Value := '00000000000000000000'B;
    var START_Value v_LAU_START_Value := '00000000000000000000'B;

    alt {
      //Step 1c1: Receive Routing Area Update Request message with update type 'RA Update'
      [] U_Dc.receive ( car_PS_InitDirectTransfer ( p_CellId,
                                                    tsc_RB3,
                                                    cr_U_RA_UpdReqAny ( cr_GMM_UpdateType ( ?, v_UpdateType_Ra ),
                                                                        cr_RAI_Any ( omit ),
                                                                        cr_PTMSI_SignatureAny ifpresent,
                                                                        ? ) ) ) -> value v_RRC_DataInd_RAU
        //FFS - Could KeySeq be derived from Security/Cell info?
      {
        //Step 1c6: Wait for Location Updating Request message
        U_Dc.receive ( car_InitDirectTransfer ( p_CellId,
                                                tsc_RB3,
                                                cr_U_LocationUpdatingRequest ) ) -> value v_RRC_DataInd_LAU;
      }
      //Step 1c6: Receive Location Updating Request message
      [] U_Dc.receive ( car_InitDirectTransfer ( p_CellId,
                                                 tsc_RB3,
                                                 cr_U_LocationUpdatingRequest ) ) -> value v_RRC_DataInd_LAU
      {
        //Step 1c1: Wait for Routing Area Update Request with update type 'RA update'
        U_Dc.receive ( car_PS_InitDirectTransfer ( p_CellId,
                                                   tsc_RB3,
                                                   cr_U_RA_UpdReqAny ( cr_GMM_UpdateType ( ?, v_UpdateType_Ra ),
                                                                       cr_RAI_Any ( omit ),
                                                                       cr_PTMSI_SignatureAny ifpresent,
                                                                       ? ) ) ) -> value v_RRC_DataInd_RAU;
        //FFS - Could KeySeq be derived from Security/Cell info?
      }
    }
    v_RAU_START_Value := v_RRC_DataInd_RAU.ttcn_start;
    v_LAU_START_Value := v_RRC_DataInd_LAU.ttcn_start;

    //Continue with the Routing Area Update Procedure
    //Step 1c2-1c3: SECURITY MODE COMMAND and SECURITY MODE COMPLETE
    f_SS_SecurityDownloadStart ( ps_domain, v_RAU_START_Value );
    f_RRC_Security ( p_CellId, false, ps_domain );
    //FFS - New security keys are not generated. Will UE use the keys that were generated in EUTRA?

    //Step 1c4: Send ROUTING AREA UPDATE ACCEPT
    U_Dc.send ( cs_PS_DataReq ( p_CellId, tsc_RB3, cs_U_RA_UpdAcc3 ( cs_GMM_UpdateResult ( v_UpdateType_Ra ),
                                                                     cs_RAI ( omit,
                                                                              cs_LAI ( omit, v_PLMN, v_LAC ),
                                                                              v_RAC ),
                                                                     cs_PTMSI_Signature ( px_PTMSI_SigDef ),
                                                                     cs_MobileIdTMSIorPTMSI ( '18'O, px_PTMSI_Def )) ) );

    // Step 1c5: Receive ROUTING AREA UPDATE COMPLETE
    U_Dc.receive ( car_PS_InitDirectTransfer ( p_CellId, tsc_RB3, cr_U_RAUpdComplete ) );

    //Then do the Location Updating Procedure
    //Step 1c7-1c8: SECURITY MODE COMMAND and SECURITY MODE COMPLETE
    f_SS_SecurityDownloadStart ( cs_domain, v_LAU_START_Value );
    //FFS - can v_LAU_START_Value be used or must it be updated?
    f_RRC_Security ( p_CellId, false, ps_domain );
    //FFS - New security keys are not generated. Will UE use the keys that were generated in EUTRA?

    //Step 1c9: Transmits a LOCATION UPDATING ACCEPT message
    U_Dc.send ( cs_DataReq ( p_CellId,
                             tsc_RB3,
                             cs_U_LocUpdAcpTMSI ( v_PLMN, v_LAC ) ) );

    //Step 1c10: Receive TMSI Reallocation Complete
    U_Dc.receive ( car_InitDirectTransfer ( p_CellId,
                                            tsc_RB3,
                                            cr_U_TMSI_ReallocCmpl ) );
  }
  
  /*
   * @desc      Performs Routing Area Update after a PS Handover from EUTRA to UTRAN has been performed, i.e.
   *            to bring UE from UTRA handover (U3) state to UTRA connected (U2) state.
   *            This procedure is according to 36.523-3 cl. 10.1.4 PS Routing Area Update procedure
   * @param     p_CellId
   * @status
   */
  function f_UTRA_PS_RAU_HO ( UTRAN_CellId_Type p_CellId ) runs on UTRAN_PTC
  {
  
    var octetstring v_Nmo := f_UTRAN_CellInfo_GetNMO ( p_CellId );
    var UTRA_POSTAMBLE_CONDITIONS v_Utra_Postamble_Condition := fl_UTRA_SetPostambleCondition ( );

    //Step 1c1 - 1c10: Perform Routing Area procedure and Location Updating procedure for the scenario
    // - NMO2 and (C1 or C3)
    if (v_Nmo == tsc_NMO_II and ((v_Utra_Postamble_Condition == UTRA_C1) or (v_Utra_Postamble_Condition == UTRA_C3))) {
      f_UTRA_Interleaved_RauLau ( p_CellId );
    }
    //Step 1a1-1a5 & 1b1-1b5 Routing Area Update/Combined Routing Area Update procedure for the scenarios
    // - NMO1 and (C1 or C3)
    // - (NMO1 or NMO2) and (C2 or C3)
    else {
      f_UTRAN_GMM_RAU_MappedContext ( p_CellId );
    }
  }
  
  /*
   * @desc      Disconnects an active CC call. To bring UE from UTRA CS call (U5) state to UTRA connected (U2) state.
   *            This procedure is according to 36.523-3 cl. 10.1.3 ( CC disconnect procedure )
   * @param     p_CellId
   * @status
   */
  function f_UTRA_CC_Disconnect ( UTRAN_CellId_Type p_CellId ) runs on UTRAN_PTC
  {
    var RB_ConfigType v_CellConfig := f_UTRAN_CellInfo_GetConfigType ( p_CellId );

    if ( v_CellConfig == cell_DCH_Speech ) {
      // Step 1: Transmit Downlink Direct Transfer with a Disconnect message
      U_Dc.send ( cs_DataReq ( p_CellId, tsc_RB3, cs_Disconnect ( cs_TI_MT ) ) );

      // Step 2: Receive Uplink Direct Transfer with a Release message
      U_Dc.receive ( car_UplinkDirectTransfer ( p_CellId, tsc_RB3, cr_Rel ( cr_TI_Any ) ) );

      // Step 3: Transmit Downlink Direct Transfer with a Release Complete message
      U_Dc.send ( cs_DataReq ( p_CellId, tsc_RB3,  cs_RelCmpl ( cs_TI_MT ) ) );

      //FFS - SS configuration and update of Cellconfig.
    }
  }

  /*
   * @desc      Brings UE from UTRA idle (U1) state or UTRA connected (U2) state to UTRA State Off
   *            This procedure is according to 36.523-3 cl. 10.1.2 (Switch/Power off procedure)
   * @param     p_CellId
   * @param     p_Utra_Postamble_State
   * @param     p_Utra_Postamble_Condition
   * @status
   */
  function f_UTRA_SwitchPower_Off ( UTRAN_CellId_Type         p_CellId,
                                    UTRA_POSTAMBLE_STATE_Type p_Utra_Postamble_State ) runs on UTRAN_PTC
  {

    var RB_ConfigType v_CellConfig := f_UTRAN_CellInfo_GetConfigType(p_CellId);
    var octetstring v_Nmo := f_UTRAN_CellInfo_GetNMO ( p_CellId );
    var integer v_AttFlag := f_UTRAN_CellInfo_GetAttFlag ( p_CellId );
    var RRC_Rel_Status v_RRC_Rel_Status := cell_Dch;
    var UTRA_POSTAMBLE_CONDITIONS v_Utra_Postamble_Condition := fl_UTRA_SetPostambleCondition ( );
    
    if ( v_CellConfig == cell_FACH ) {
      v_RRC_Rel_Status := cell_Fach_Dcch;
    };

    //Step 1: The UE can be switched off
    if ( pc_SwitchOnOff == true ) {
      //Step 1: The UE is switched off
      f_UT_SwitchOffUE(UT, false);

      //Step 2-4: RRC Connection establishment when UE is in UTRA idle end state
      if ( p_Utra_Postamble_State == U1_IDLE ) {
        f_UTRAN_RRC_ConnEst ( p_CellId, est_MO, detach );
      }
      alt
      {
        //Step 5a1, 5c1 & 5d1: Receive Detach Request message for the different scenarios
        // - NMO1 and (C1 or C3) : detach type = power switched off, GPRS/IMSI combined detach
        // - (NMO1 or NMO2) and C2 : detach type = power switched off, PS detach
        // - NMO2 and (C1 or C3) : detach type = power switched off, PS detach
        [] U_Dc.receive ( car_PS_InitDirectTransfer ( utran_CellDedicated,
                                                      tsc_RB3,
                                                      cr_U_DetachRequest ( cr_DetachTypeOnSwitchOff,
                                                                           cdr_MobileIdTMSI_tlv(?),
                                                                           cr_PTMSI_SignatureAny ifpresent ) ) )
        {
          //Step 5b1 & 5d2: Receive IMSI Detach indication for the different scenario
          // - (NMO1 or NMO2) and C4
          // - NMO2 and (C1 or C3)
          if ( v_AttFlag == 1 and
               ( (v_Nmo == tsc_NMO_II and (v_Utra_Postamble_Condition == UTRA_C1 or v_Utra_Postamble_Condition == UTRA_C3)) or
               (v_Utra_Postamble_Condition == UTRA_C4) ) ) {
            U_Dc.receive ( car_InitDirectTransfer ( utran_CellDedicated,
                                                    tsc_RB3,
                                                    cr_U_Imsi_DetachInd ) );
          }
          //Step 6-7: Release RRC connection when the UE has been switched off
          f_UTRAN_RRC_ConnRel_AfterSwitchOff ( p_CellId, v_RRC_Rel_Status );
        }
        // Step 5d2: Receive IMSI detach Indication
        // When NMO2 and (C1 or C3) : CS and PS are run independently and SS shall accept either PS detach first or IMSI detach first.
        [] U_Dc.receive ( car_InitDirectTransfer ( utran_CellDedicated,
                                                   tsc_RB3,
                                                   cr_U_Imsi_DetachInd ) )
        {
          //Step 5d1: Receive Detach request for the scenario
          // - NMO2 and (C1 or C3)
          if ( v_AttFlag == 1 and
               v_Nmo == tsc_NMO_II and
               (v_Utra_Postamble_Condition == UTRA_C1 or v_Utra_Postamble_Condition == UTRA_C3) ) {
            U_Dc.receive ( car_PS_InitDirectTransfer ( utran_CellDedicated,
                                                       tsc_RB3,
                                                       cr_U_DetachRequest ( cr_DetachTypeOnSwitchOff,
                                                                            cdr_MobileIdTMSI_tlv(?),
                                                                            cr_PTMSI_SignatureAny ifpresent ) ) );
            
            //Step 6-7: Release RRC connection when the UE has been switched off
            f_UTRAN_RRC_ConnRel_AfterSwitchOff ( p_CellId, v_RRC_Rel_Status );
          }
          else {//IMSI Detach only
            //Step 6-7: Release RRC Connection
            f_UTRAN_RRC_ConnRel ( p_CellId, v_RRC_Rel_Status );
          }
        }
      }
    }
    //Step 1: The power must be removed from the UE
    else {
      f_UT_PowerOffUE (UT);
    }
  }

  /*
   * @desc      Function to set the postamble conditions based on the UTRA CS/PS domain support
   *            and the LTE UE Attach type. According to 36.523-3 Table 10.1-1
   * @return    UTRA_POSTAMBLE_CONDITIONS
   * @status
   */
  function fl_UTRA_SetPostambleCondition ( ) runs on UTRAN_PTC return UTRA_POSTAMBLE_CONDITIONS
  {
    
    var boolean v_IsCombined := fl_UTRA_AttachTypeCheck();
    var UTRA_POSTAMBLE_CONDITIONS v_UTRA_POSTAMBLE_CONDITION := UTRA_C1;

    if ( v_IsCombined ) {//combined attach case
      if ( pc_CS and pc_PS ) {
          v_UTRA_POSTAMBLE_CONDITION := UTRA_C3
        }
      else if ( pc_CS and (not pc_PS) ) {
        v_UTRA_POSTAMBLE_CONDITION := UTRA_C4
      }
    }
    else {//attach case
      if ( pc_PS and (not pc_CS) ) {
        v_UTRA_POSTAMBLE_CONDITION := UTRA_C2
      }
    }
    return v_UTRA_POSTAMBLE_CONDITION;
  }

  /*
   * @desc      Copy of fl_AttachTypeCheck. Checks the set parameters pc_Combined_Attach, pc_Attach & px_AttachTypeTested
   *            and returns a boolean (TRUE is attach is combined, false if attach is EPS only)
   * @return    boolean
   * @status
   */
  function fl_UTRA_AttachTypeCheck () runs on UTRAN_PTC return boolean
  {
    var boolean v_IsCombined := false;
    if( pc_Combined_Attach) {
      if (pc_Attach) { // So both set to true
        if (px_AttachTypeTested == COMBINED_ATTACH) { // only now check the PIXIT value
          v_IsCombined := true;
        }
      } else { // only combined set to true
          v_IsCombined := true;
      }
    } else if (not pc_Attach) { // so neither set to true
          f_UTRAN_SetVerdictFailOrInconc(__FILE__, __LINE__, "Neither pc_Attach nor pc_Combined_Attach set to true");
    }
    return v_IsCombined;
  }

  /*
   * @desc      Function to bring UE to switched/powered off state after test case execution in UTRA PTC
                This procedure is according to 36.523-3 cl. 10.1
   * @param     p_CellId
   * @param     p_UTRA_POSTAMBLE_STATE; as defined in 36.508 cl. 6.4.3.2
   * @status
   */
  function f_UTRA_Postamble ( UTRAN_CellId_Type         p_CellId,
                              UTRA_POSTAMBLE_STATE_Type p_UTRA_POSTAMBLE_STATE ) runs on UTRAN_PTC
  {
    select ( p_UTRA_POSTAMBLE_STATE ) {
      case ( U1_IDLE ) {
        //Switch/Power off UE
        f_UTRA_SwitchPower_Off ( p_CellId, U1_IDLE );
      }
      case ( U2_CONNECTED ) {
        //Switch/Power off UE
        f_UTRA_SwitchPower_Off ( p_CellId, U2_CONNECTED );
      }
      case ( U3_HANDOVER ) {
        //Routing Area Procedures
        f_UTRA_PS_RAU_HO ( p_CellId );

        //Switch/Power off UE
        f_UTRA_SwitchPower_Off ( p_CellId, U2_CONNECTED );
      }
      case ( U4_CSFALLBACK ) {
        //Perform CS Fallback procedure
        f_UTRA_CS_Fallback ( p_CellId );

        //Switch/Power off UE
        f_UTRA_SwitchPower_Off ( p_CellId, U2_CONNECTED );
      }
      case ( U5_CSCALL ) {
        //Disconnect the active CC call
        f_UTRA_CC_Disconnect ( p_CellId );
        
        //SwitchPower off UE
        f_UTRA_SwitchPower_Off ( p_CellId, U2_CONNECTED );
      }
      case (U6_DEREGISTERED) {
        //If the UE can be switched off
        if ( pc_SwitchOnOff == true ) {
          //Simply switch the UE off
          f_UT_SwitchOffUE(UT, false);
        } else {//just remove power from UE
        f_UT_PowerOffUE ( UT );
        }
      }
      case else {//No state defined - just remove power from UE
        f_UT_PowerOffUE ( UT );
      }
    }
    //Release the UTRA cell
    f_UTRAN_ReleaseCell ( p_CellId );
  }

  /*
   * @desc      Function used in Idle Mode test cases to perform Routing Area Update on the new UTRAN cell.
   * @param     p_CellId
   * @param     p_RRC_RelStatus
   * @status
   */
  function f_UTRAN_IdleMode_RAU ( UTRAN_CellId_Type p_CellId,
                                  RRC_Rel_Status    p_RRC_RelStatus :=  cell_Fach_Dcch ) runs on UTRAN_PTC
  {
    timer t_IdleMode_GenericTimer := f_UG_SetTimerToleranceMax (tsc_IdleMode_GenericTimer_UTRAN);
    
    t_IdleMode_GenericTimer.start;
    f_UTRAN_508CheckCampOnNewUtranCell ( p_CellId, p_RRC_RelStatus );
    t_IdleMode_GenericTimer.stop;
  }

  /*
   * @desc      Procedure which aims at checking whether the UE is camping on a new UTRAN cell
   *            of a test case or not. The procedure is defined in 36.508 table 6.4.2.8-1.
   * @param     p_CellId
   * @param     p_RRC_RelStatus
   * @status
  */
  function f_UTRAN_508CheckCampOnNewUtranCell ( UTRAN_CellId_Type p_CellId,
                                                RRC_Rel_Status p_RRC_RelStatus :=  cell_Fach_Dcch ) runs on UTRAN_PTC
  {

    //Step 1-3: Establish RRC Connection
    f_UTRAN_RRC_ConnEst ( p_CellId, est_Reg, registration );
    f_UTRAN_PreliminaryPass(__FILE__, __LINE__, "");
    
    //Step 4-10: Routing Area Update, Authentication and RRC Security
    f_UTRAN_GMM_RAU_MappedContext ( p_CellId );
    
    //Step 11-12: Release RRC Connection
    f_UTRAN_RRC_ConnRel ( p_CellId, p_RRC_RelStatus );
    f_UTRAN_PreliminaryPass(__FILE__, __LINE__, "");
  }

  /*
   * @desc      Always to be used when just arrived from EUTRA and are NOT doing a new Authentication
   *            This function is according to 36.508 cl. 6.4.2.8    Test procedure to check that UE is camped on a new UTRAN cell (steps 4-10)
   * @param     p_CellId
   * @status
  */
  function f_UTRAN_GMM_RAU_MappedContext(UTRAN_CellId_Type p_CellId) runs on UTRAN_PTC
  {
    f_UTRAN_GMM_RAU ( p_CellId, false );
  };

  /*
   * @desc      Performs the Routing Area Procedure (except receiving the RAU Request message).
   *            Execution of Authentication is dependent on input parameter p_DoAuth
   * @param     p_CellId
   * @param     p_START_Value
   * @param     p_UpdateType
   * @param     p_DoAuth
   * @status
  */
  function f_UTRAN_GMM_RAU_Without_RAUReq ( UTRAN_CellId_Type p_CellId,
                                            START_Value       p_START_Value,
                                            B3_Type           p_UpdateType,
                                            boolean           p_DoAuth := true ) runs on UTRAN_PTC
  {
    var octetstring v_PLMN := f_U_Asn2Nas_PlmnId(f_UTRAN_CellInfo_GetPLMNIdentity(p_CellId));
    var octetstring v_LAC := f_UTRAN_CellInfo_GetLAC(p_CellId);
    var octetstring v_RAC := f_UTRAN_CellInfo_GetRAC(p_CellId);

    f_SS_SecurityDownloadStart(ps_domain, p_START_Value);
    
    if ( p_DoAuth ) {
      f_GMM_Authentication();
    }

    f_RRC_Security(p_CellId,                        // SECURITY MODE COMMAND, SECURITY MODE COMPLETE
                   p_DoAuth,
                   ps_domain);
    
    U_Dc.send (cs_PS_DataReq(utran_CellDedicated,
                             tsc_RB3,
                             cs_U_RA_UpdAcc3 (cs_GMM_UpdateResult (p_UpdateType),
                                              cs_RAI (omit,
                                                      cs_LAI(omit, v_PLMN, v_LAC),
                                                      v_RAC ),
                                              cs_PTMSI_Signature (px_PTMSI_SigDef),
                                              cs_MobileIdTMSIorPTMSI ('18'O, px_PTMSI_Def))));
    
    U_Dc.receive(car_PS_UplinkDirectTransfer(utran_CellDedicated, tsc_RB3, cr_U_RAUpdComplete ));
  };

  /*
   * @desc      This function is according to 36.508 cl. 6.4.2.8    with the exception that when p_DoAuth is set to true
   *            the function also performs Authentication procedure (
   * @param     p_CellId
   * @param     p_DoAuth
   * @status
  */
  function f_UTRAN_GMM_RAU(UTRAN_CellId_Type p_CellId,
                           boolean           p_DoAuth := true ) runs on UTRAN_PTC
  {
    var START_Value v_START_Value := '00000000000000000000'B;
    var B3_Type v_UpdateType := '000'B;
    var RRC_DATA_IND v_RRC_DataInd;
    
    alt{
      [] U_Dc.receive(car_PS_InitDirectTransfer(utran_CellDedicated,
                                                tsc_RB3,
                                                cr_U_RA_UpdReqAny (cr_GMM_UpdateType(?,?),
                                                                   cr_RAI_Any (omit),
                                                                   cr_PTMSI_SignatureAny ifpresent,
                                                                   ? ) ))
        -> value v_RRC_DataInd {
        v_START_Value := v_RRC_DataInd.ttcn_start;
        f_SS_SecurityDownloadStart(ps_domain, v_START_Value);
        v_UpdateType := v_RRC_DataInd.msg.routingAreaUpdateRequest.updateType.updateValue;
        if (v_UpdateType != '000'B) {
          v_UpdateType := '001'B;
        }
      }
    }
    f_UTRAN_GMM_RAU_Without_RAUReq ( p_CellId, v_START_Value, v_UpdateType, p_DoAuth );
  }
  
  /*
   * @desc      To release RRC connection to be used in cases where the UE has been switched off
   * @param     p_CellId
   * @param     p_RRC_RelStatus
   * @status
  */
  function f_UTRAN_RRC_ConnRel_AfterSwitchOff(UTRAN_CellId_Type p_CellId,
                                              RRC_Rel_Status    p_RRC_RelStatus) runs on UTRAN_PTC
  {

    var UTRAN_SecurityInfo_Type v_SecurityInfo := f_UTRAN_Security_Get();
    var integer v_N308 := 1;     // Maximum number of retransmissions of the RRC CONNECTION RELEASE COMPLETE message.
    var integer v_K := 0;
    timer t_WaitForReply := f_UG_SetTimerToleranceMax (1.0);
    
    f_Delay(1.0);
    
    if (p_RRC_RelStatus == cell_Dch) {
      U_UM.send(cas_RRC_ConnRelDCCH(utran_CellDedicated,
                                    tsc_RB1,
                                    cs_108_RRC_ConnRelDCCH_r4(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                              tsc_RRC_TI,
                                                              v_N308)));
      for (v_K := 0; v_K < (v_N308 + 1); v_K := v_K + 1) {
        t_WaitForReply.start;
        alt {
          [] t_WaitForReply.timeout {} // UE may not send the Release Complete
          [] U_UM.receive(car_RRC_ConnRelCmplUM(utran_CellDedicated,
                                              tsc_RB1,
                                              cr_108_RRC_ConnRelCmpl(tsc_RRC_TI)))
            {
              t_WaitForReply.stop;
            }
          }
        }
    } else if (p_RRC_RelStatus == cell_Fach_Dcch) {
      U_UM.send(cas_RRC_ConnRelDCCH(utran_CellDedicated,
                                    tsc_RB1,
                                    cs_108_RRC_ConnRelDCCH_r4(v_SecurityInfo.dl_IntegrityCheckInfo,
                                                              tsc_RRC_TI,
                                                              omit)));
      t_WaitForReply.start;
      alt {
        [] t_WaitForReply.timeout {} // UE may not send the Release Complete
        [] U_AM.receive ( car_RLC_Data_Ind ( utran_CellDedicated,
                                             tsc_RB2,
                                             cr_108_RRC_ConnRelCmpl(tsc_RRC_TI)))
          {
            t_WaitForReply.stop;
            f_Delay(1.0);
          }}
      
    } else if (p_RRC_RelStatus == cell_Fach_Ccch) {
      U_UM.send(cas_RRC_ConnRelCCCH(p_CellId,
                                    tsc_RB0,
                                    cs_108_RRC_ConnRelCCCH_r5(cs_U_RNTI_Def, tsc_RRC_TI)));
    } else {
      FatalError(__FILE__, __LINE__, "invalid configuration");
    }
    
    //  TO DO - Implement DPCH re-configuration
    f_RestartCRLC_ForNextConnection(p_CellId);
    f_SS_ResetSecurityKey();
  }

  /*
   * @desc      Perform the Location Updating procedure including activation of Security
   * @param     p_CellId
   * @status
   */
  function f_UTRAN_LocationUpdate( UTRAN_CellId_Type p_CellId ) runs on UTRAN_PTC
  {
    var START_Value v_START_Value := '00000000000000000000'B;
    var octetstring v_PLMN := f_U_Asn2Nas_PlmnId(f_UTRAN_CellInfo_GetPLMNIdentity(p_CellId));
    var octetstring v_LAC := f_UTRAN_CellInfo_GetLAC(p_CellId);
    var boolean v_NewKeyFlag := false;//No new key generation
    var RRC_DATA_IND v_RRC_DataInd;
    
    //Receive Location Updating Request message
    U_Dc.receive(car_InitDirectTransfer(utran_CellDedicated, tsc_RB3, cr_U_LocationUpdatingRequest)) -> value v_RRC_DataInd;

    v_START_Value := v_RRC_DataInd.ttcn_start;
    f_SS_SecurityDownloadStart(cs_domain, v_START_Value);

    //Send SECURITY MODE COMMAND and receive SECURITY MODE COMPLETE
    f_RRC_Security(p_CellId, v_NewKeyFlag, cs_domain );
    
    //Send Location Updating Accept message
    U_Dc.send (cs_DataReq(utran_CellDedicated, tsc_RB3, cs_U_LocUpdAcpTMSI (v_PLMN, v_LAC)));

    //Receive TMSI Reallocation Complete
    U_Dc.receive(car_InitDirectTransfer(utran_CellDedicated, tsc_RB3, cr_U_TMSI_ReallocCmpl ));
  }

  /*
   * @desc
   * @param     p_CellId
   * @param     p_Wait
   * @param     p_StepNo
   * @status
   */
  function f_UTRAN_CheckNoAttachOnCell ( UTRAN_CellId_Type p_CellId, float p_Wait, charstring p_StepNo ) runs on UTRAN_PTC
  {
    var InitialUE_Identity v_InitialUE_Id;
    var AccessStratumReleaseIndicator  v_RelInd;
    var RLC_TR_DATA_IND v_RLC_TR_DATA_IND;
  
    timer t_Wait := f_UG_SetTimerToleranceMin(p_Wait);
    t_Wait.start;
    alt {
      [] U_TM.receive(car_RRC_ConnReq(p_CellId,
                                    tsc_RB0,
                                    cdr_RRC_ConnReq_r8OrLater(?)))
        -> value v_RLC_TR_DATA_IND {
        v_InitialUE_Id := v_RLC_TR_DATA_IND.tM_message.uL_CCCH_Message.message_.rrcConnectionRequest.initialUE_Identity;
        v_RelInd := v_RLC_TR_DATA_IND.tM_message.uL_CCCH_Message.message_.rrcConnectionRequest.v3d0NonCriticalExtensions.v4b0NonCriticalExtensions.rrcConnectionRequest_v4b0ext.accessStratumReleaseIndicator;
        f_UTRAN_SetVerdictFailOrInconc (__FILE__, __LINE__, p_StepNo);

      }
      []   t_Wait.timeout
        {
          f_UTRAN_PreliminaryPass (__FILE__, __LINE__, p_StepNo);
        }
    }
  } // f_UTRAN_CheckNoAttachOnCell
}
