/******************************************************************************/
// @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-08 10:25:40 +0200 (Wed, 08 Sep 2010) $
// $Rev: 3833 $
/******************************************************************************/
module CSG_Testcases
{
//=========================================================================
// Imports
//=========================================================================

  import from EUTRA_RRC_ASN1_Definitions language "ASN.1:1997" all;
  import from Parameters all;
  import from CommonDefs all;
  import from UpperTesterFunctions all;
  import from EUTRA_CellInfo  all;
  import from EUTRA_Component all;
  import from EUTRA_CommonDefs all;
  import from EUTRA_IdleMode all;
  import from EUTRA_CommonProcedures all;
  import from EUTRA_NASSteps all;
  import from EUTRA_ConfigurationSteps all;
  import from EUTRA_SRB_Templates all;
  import from EUTRA_RRC_Templates all;
  import from EUTRA_AspCommon_Templates all;
  import from EUTRA_NASCommonFunctions all;
  import from EUTRA_IRATFunctions all;
  
  import from EUTRA_SysInfo_Templates all;
  import from CommonIratDefs all;
  
//==============================================================================
// Types
//==============================================================================
  
  type PhysCellIdRange.range PhysCellIdRange_Type;
  
//==============================================================================
// Templates
//==============================================================================

  template (value) IntraFreqNeighCellList cs_IntraFreqNeighCellInfoList_Cell2_ThreeEntriesDef :=
  {
    {
      physCellId := 1,
      q_OffsetCell := dB0
    },
    {
      physCellId := 4,
      q_OffsetCell := dB0
    },
    {
      physCellId := 11,
      q_OffsetCell := dB0
    }
  }
  
  template (value) SystemInformationBlockType4 cs_SIB4_IntraFreqNeighCellList_and_Csg_PhysCellIdRange ( template (value) IntraFreqNeighCellList  p_IntraFreqNeighCellList,
                                                                                                        template (value) PhysCellIdRange         p_PhysCellIdRange  ) :=
    cs_SIB4_AllParameters (p_IntraFreqNeighCellList, omit, p_PhysCellIdRange);

  template (value) PhysCellIdRange cs_PhysCellIdRange ( PhysCellId           p_Start,
                                                        PhysCellIdRange_Type p_Range ) := {
    start_ := p_Start,
    range := p_Range
  }

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

  /*
   * @desc      REFERENCE TS 36.523-1 clause 6.3.3
   * @status
   */
  function f_TC_6_3_3_EUTRA ( ) runs on EUTRA_PTC {
  
    var template (value) CellPowerList_Type v_CellPowerList_T0toT1, v_CellPowerList_T1toT2, v_CellPowerList_T2toT3, v_CellPowerList_T3toT4;
    var EUTRA_FDD_TDD_Mode_Type v_FDD_TDD_Cell1;
    var IRAT_CoOrd_SysInfo_Type v_UTRANSysInfo;
    var B27_Type v_CSG_Identity_Cell2 := '000000000000000000000000001'B;
    var CellReselectionPriority v_CellReselectionPriority_Cell5 := 5;
    var boolean v_TriggerRxd := false;
    
    v_CellPowerList_T0toT1 := {
      cs_CellPower ( eutra_Cell1, -91 ),
      cs_CellPower ( eutra_Cell2, tsc_ServingCellRS_EPRE )
    };
    v_CellPowerList_T1toT2 := {
      cs_CellPower ( eutra_Cell1, tsc_NonSuitableOffCellRS_EPRE ),
      cs_CellPower ( eutra_Cell2, tsc_NonSuitableOffCellRS_EPRE )
    };
    v_CellPowerList_T2toT3 := {
      cs_CellPower ( eutra_Cell1, tsc_ServingCellRS_EPRE )
    };
    v_CellPowerList_T3toT4 := {
      cs_CellPower ( eutra_Cell1, -91 ),
      cs_CellPower ( eutra_Cell2, tsc_ServingCellRS_EPRE )
    };
    
    //Initialise all cells, security and mobile parameters
    f_EUTRA_Init(c4);//SIB2, SIB3 and SIB6 are transmitted
    
    //Coordinate with UTRAN component to receive UTRAN frequencies
    v_UTRANSysInfo := f_WaitForIRATCoOrd_SysInfo (UTRAN);
    
    //Send the cell info to the UTRAN component
    f_IRAT_Send_EUTRA_SysInfoToOtherPort(UTRAN, f_EUTRA_CellInfo_GetEARFCN_DL(eutra_Cell1));

    //Set TAC according to 36.523-1 Table 6.0.4-2: Tracking Area Code (TAC) for E-UTRAN cells
    //TAC for Cell 1 is set to 1 in f_EUTRA_Init
    f_EUTRA_CellInfo_SetTAC ( eutra_Cell2, tsc_IdleMode_TAC_Cell2 );
    
    //Get FDD or TDD mode
    v_FDD_TDD_Cell1 := f_EUTRA_CellInfo_GetFDD_TDD (eutra_Cell1);
    
    //Change System Information Combination of cell 1
    f_EUTRA_ChangeSysinfoCombination (eutra_Cell2, c11);
    
    //Set Sys. info for Cell 2 according to Table 6.3.3.3.3-2
    f_EUTRA_CellInfo_SetSysInfo_Csg_Ind(eutra_Cell2, true);
    f_EUTRA_CellInfo_SetSysInfo_Csg_Id(eutra_Cell2, v_CSG_Identity_Cell2);
    
    //Set SIB4 for cell 2 according to Table 6.3.3.3.3-3 and according to default message contents defined in 36.508
    f_EUTRA_CellInfo_SetSIB4 ( eutra_Cell2, cs_SIB4_IntraFreqNeighCellList_and_Csg_PhysCellIdRange ( cs_IntraFreqNeighCellInfoList_Cell2_ThreeEntriesDef,
                                                                                                     cs_PhysCellIdRange(2, n4)) );

    //Set SIB6 for cell 1 and 2 according to Table 6.3.3.3.3-5
    if ( v_FDD_TDD_Cell1 == FDD ){//Since we do not have mixed FDD/TDD InterRat environment.
      f_EUTRA_CellInfo_SetSIB6 ( eutra_Cell1,
                                 cs_508_SystemInformationBlockType6_Def ( { cs_CarrierFreqUTRA_FDD_CRPrio ( v_UTRANSysInfo.Utran[0].FDD.Freq,
                                                                                                            v_CellReselectionPriority_Cell5 ) }, omit ) );
      f_EUTRA_CellInfo_SetSIB6 ( eutra_Cell2,
                                 cs_508_SystemInformationBlockType6_Def ( { cs_CarrierFreqUTRA_FDD_CRPrio ( v_UTRANSysInfo.Utran[0].FDD.Freq,
                                                                                                            v_CellReselectionPriority_Cell5 ) }, omit ) );
    }
    else {
      f_EUTRA_CellInfo_SetSIB6 ( eutra_Cell2,
                                 cs_508_SystemInformationBlockType6_Def ( omit,
                                                                          { cs_CarrierFreqUTRA_TDD_CRPrio ( v_UTRANSysInfo.Utran[0].TDD.Freq,
                                                                                                            v_CellReselectionPriority_Cell5 ) } ) );
      f_EUTRA_CellInfo_SetSIB6 ( eutra_Cell2,
                                 cs_508_SystemInformationBlockType6_Def ( omit,
                                                                          { cs_CarrierFreqUTRA_TDD_CRPrio ( v_UTRANSysInfo.Utran[0].TDD.Freq,
                                                                                                            v_CellReselectionPriority_Cell5 ) } ) );
    }
        
    //Create and configure Cells
    f_EUTRA_CellConfig_Def(eutra_Cell1);
    f_EUTRA_CellConfig_Def(eutra_Cell2);

    f_EUTRA_TestBody_Set ( true );
    
    //Since Authentication parameters were updated in the idle updated procedure on UTRAN side...
    //...receive the updated parameters
    f_EUTRA_InterRAT_InitialiseAuthParams(UTRAN);
    
    //@siclog "Step 14" siclog@
    //Change Cell 1 and Cell 2 power levels according to the row "T1" in table 6.3.3.3.2-1.
    f_EUTRA_SetCellPowerList ( v_CellPowerList_T0toT1, cs_TimingInfo_Now );
    
    //@siclog "Step 15" siclog@
    //Perform manual selection of cell 2
    f_UT_ManualPLMN_Select (UT, "00101");
    //FFS - for now there is no Manual CSG cell selection command that can be used
    
    //@siclog "Step 16" siclog@
    //Check that UE camps on Cell 1 with the generic test procedure TS 36.508 subclause 6.4.2.7A
    f_EUTRA_IdleMode_TAU_UponMobility_FromOtherRAT ( eutra_Cell2 );
    
    //@siclog "Step 17" siclog@
    //Change Cell 1, Cell 2, Cell 5 and Cell 7 levels according to row "T2" in table 6.3.3.3.2-1 and table 6.3.3.3.2-2.
    f_SendIRATCoOrd ( UTRAN, cms_IRAT_Trigger );
    f_EUTRA_SetCellPowerList ( v_CellPowerList_T1toT2, cs_TimingInfo_Now );
    
    //@siclog "Step 30" siclog@
    //Change Cell 1, Cell 2, Cell 5 and Cell 7 levels according to row "T3" in table 6.3.3.3.2-1 and table 6.3.3.3.2-2.
    v_TriggerRxd := f_WaitForIRATCoOrd_Trigger (UTRAN);
    f_EUTRA_SetCellPowerList ( v_CellPowerList_T2toT3, cs_TimingInfo_Now );
    
    //@siclog "Step 44" siclog@
    //Change Cell 1 and Cell 2 level according to row "T4" in table 6.3.3.3.2-1.
    v_TriggerRxd := f_WaitForIRATCoOrd_Trigger (UTRAN);
    f_EUTRA_SetCellPowerList ( v_CellPowerList_T3toT4, cs_TimingInfo_Now );
    
    //@siclog "Step 45" siclog@
    //Check that UE camps on Cell 1 with the generic test procedure TS 36.508 subclause 6.4.2.7A
    f_EUTRA_IdleMode_TAU_UponMobility_FromOtherRAT ( eutra_Cell2 );

    f_EUTRA_TestBody_Set ( false );

    //Switch/Power off UE
    f_EUTRA_Postamble ( eutra_Cell2, E1_IDLE );
  }

  /*
   * @desc      REFERENCE TS 36.523-1 clause 6.3.6
   * @status
   */
  function f_TC_6_3_6_EUTRA ( ) runs on EUTRA_PTC
  {
    var template (value) CellPowerList_Type v_CellPowerList_AtT0;
    var template (value) CellPowerList_Type v_CellPowerList_AtT1;
    var template (value) CellPowerList_Type v_CellPowerList_AtT2;
    var template (value) CellPowerList_Type v_CellPowerList_AtT3;
    var Q_Rxlevmin_Type v_Q_Rxlevmin := -55;
    var Q_Hyst_Type v_Q_Hyst := dB0;
    var B27_Type v_CSG_Identity_Cell2 := '000000000000000000000000010'B;
    var B27_Type v_CSG_Identity_Cell3 := '000000000000000000000000011'B;

    var float v_WaitTime := 60.0;
    timer t_IdleMode_GenericTimer := tsc_IdleMode_GenericTimer;

    v_CellPowerList_AtT0 := {
      cs_CellPower ( eutra_Cell1, -115 ),
      cs_CellPower ( eutra_Cell2, -97 ),
      cs_CellPower ( eutra_Cell3, -85 )
    };
    v_CellPowerList_AtT1 := {
      cs_CellPower ( eutra_Cell1, -97 ),
      cs_CellPower ( eutra_Cell2, -73 )
    };
    v_CellPowerList_AtT2 := {
      cs_CellPower ( eutra_Cell1, -85 ),
      cs_CellPower ( eutra_Cell2, -79 ),
      cs_CellPower ( eutra_Cell3, -115 )
    };
    v_CellPowerList_AtT3 := {
      cs_CellPower ( eutra_Cell2, -115 ),
      cs_CellPower ( eutra_Cell3, -73 )
    };

    //Initialise all cells, security and mobile parameters
    f_EUTRA_Init(c3);//SIB2, SIB3 & SIB5 are transmitted

    //Change System Information Combination of cell 1
    f_EUTRA_ChangeSysinfoCombination ( eutra_Cell1, c1 );

    //Set maximum cell powel level for Cell 1, 2 & 3
    f_EUTRA_CellInfo_InitMaxReferencePower ( eutra_Cell2, -73 );
    f_EUTRA_CellInfo_InitMaxReferencePower ( eutra_Cell3, -73 );

    //Set Sys. info for Cell 1, 2, & 3 to be used in creation
    f_EUTRA_CellInfo_SetSysInfo_Csg_Ind ( eutra_Cell2, true );
    f_EUTRA_CellInfo_SetSysInfo_Csg_Ind ( eutra_Cell3, true );
    f_EUTRA_CellInfo_SetSysInfo_Csg_Id ( eutra_Cell2, v_CSG_Identity_Cell2 );
    f_EUTRA_CellInfo_SetSysInfo_Csg_Id ( eutra_Cell3, v_CSG_Identity_Cell3 );
    f_EUTRA_CellInfo_SetSysInfo_Q_Rxlevmin ( eutra_Cell1, v_Q_Rxlevmin );
    f_EUTRA_CellInfo_SetSysInfo_Q_Rxlevmin ( eutra_Cell2, v_Q_Rxlevmin );
    f_EUTRA_CellInfo_SetSysInfo_Q_Rxlevmin ( eutra_Cell3, v_Q_Rxlevmin );
    f_EUTRA_CellInfo_SetSysInfo_Q_Hyst ( eutra_Cell1, v_Q_Hyst );
    f_EUTRA_CellInfo_SetSysInfo_Q_Hyst ( eutra_Cell2, v_Q_Hyst );
    f_EUTRA_CellInfo_SetSysInfo_Q_Hyst ( eutra_Cell3, v_Q_Hyst );
    f_EUTRA_CellInfo_SetSIB4 ( eutra_Cell2, cs_SIB4_Csg_PhysCellIdRange_StartOnly ( 2 ) );
    f_EUTRA_CellInfo_SetSIB4 ( eutra_Cell3, cs_SIB4_Csg_PhysCellIdRange_StartOnly ( 3 ) );

    //Create and configure Cell 1
    f_EUTRA_CellConfig_Def ( eutra_Cell1 );
    f_EUTRA_CellConfig_Def ( eutra_Cell2 );
    f_EUTRA_CellConfig_Def ( eutra_Cell3 );

    if ( pc_Allowed_CSG_list ) {
      //Autonumous procedure to empty the UE's Allowed CSG list is FFS - for now use USIM with service n86 available
        /* 24.301 Annex C
         * The following EMM parameters shall be stored on the USIM if the corresponding file is present:
         * ...
         * - Allowed CSG list; and
         * ...
         * If the corresponding file is not present on the USIM, these EMM parameters except allowed CSG list are stored
         * in a non-volatile memory in the ME together with the IMSI from the USIM.
         * The allowed CSG list is stored in a non-volatile memory in the ME if the UE supports CSG selection.
        */
        /* Questions:
         * 1. The UE will consider its Allowed CSGs List as valid until it receives a new list from the network
              (e.g. in the next normal tracking area update or periodic tracking area update) or it is commanded by
              the network to delete all TACs in the Allowed CSGs List.
              How can UE be commanded to delete all TACs in the Allowed CSG list?
         * 2. Is the Allowed CSG List cleared at power down?
         * 3. Is there any mapping between TAI list and Allowed CSG list => CSG Mobility list?
        */
        /* Assumptions
          24.801 cl. 10.12.2.4
           "The working assumption is that the allowed CSG list shall be stored in the UICC and,
            as an implementation option, can be stored additionally in the ME. If stored in the ME,
            when the ME detects that the UICC has been changed, the CSG list will be deleted from the ME."
          24.801 cl. 10.12.3.4
           "The UE will store the Allowed CSGs list either in the ME or in the USIM and it will consider
            its Allowed CSGs list as valid until it receives a new list in the next EMM procedure or it is commanded
            by the network to delete all entries in the Allowed CSGs list"
        */
      //Insert a USIM containing default values expect service n86 (TS 31.102) is "available", but the Allowed CSG List shall be empty
      f_UT_USIM_Insert ( UT, "USIM with serivce n86 available, but the Allowed CSG List shall be empty" );
    }

    //Preamble to ensure UE is in stable state
    f_EUTRA_Preamble ( eutra_Cell1, STATE2_IDLEUPDATE );

    //Bring UE to initial state
    f_EUTRA_UE_Detach_SwitchOffUe ( eutra_Cell1, RRC_IDLE );

    //Set cell power level according to T0
    f_EUTRA_SetCellPowerList ( v_CellPowerList_AtT0, cs_TimingInfo_Now );

    f_EUTRA_TestBody_Set ( true );

    //@siclog "Step 1" siclog@
    //Switch on UE
    f_UT_SwitchOnUE (UT, false);

    //@siclog "Step 2" siclog@
    //Check for no RRCConnectionRequest message on Cell 2 & 3
    f_EUTRA_CheckNoAttachOn2Cells ( eutra_Cell2,
                                    eutra_Cell3,
                                    v_WaitTime,
                                    "Step 2: RRCConnectionRequest message received on Cell 2 or 3");

    //@siclog "Step 3" siclog@
    //Set cell power levels according to T1
    f_EUTRA_SetCellPowerList ( v_CellPowerList_AtT1, cs_TimingInfo_Now );
    t_IdleMode_GenericTimer.start;

    //@siclog "Step 4" siclog@
    //Receive RRCConnectionRequest in cell 1
    SRB.receive( car_SRB0_RrcPdu_IND ( eutra_Cell1, cr_508_RRCConnectionRequest ) );
    //Stop Idle Mode Geberic Timer
    t_IdleMode_GenericTimer.stop;
    // @verdict pass RRCConnectionRequest message received on Cell 1
    f_EUTRA_PreliminaryPass (__FILE__, __LINE__, "Test Case 6.3.6 Step 4");

    //@siclog "Step 5 - 19" siclog@
    //Perform step 3 to 17 of the registration procedure defined in 36.508 cl. 4.5.2.3
    f_EUTRA_IdleUpdated_WithoutRRCConnReq ( eutra_Cell1, STATE2_IDLEUPDATE );

    //@siclog "Step 20" siclog@
    //Set cell power levels according to T2
    f_EUTRA_SetCellPowerList ( v_CellPowerList_AtT2, cs_TimingInfo_Now );

    //@siclog "Step 21" siclog@
    //Check for no RRCConnectionRequest message on Cell 2 & 3
    f_EUTRA_CheckNoAttachOn2Cells ( eutra_Cell2,
                                    eutra_Cell3,
                                    v_WaitTime,
                                    "Step 21: RRCConnectionRequest message received on Cell 2 or 3");

    //@siclog "Step 22" siclog@
    //Set cell power levels according to T3
    f_EUTRA_SetCellPowerList ( v_CellPowerList_AtT3, cs_TimingInfo_Now );

    //@siclog "Step 23" siclog@
    //Check for no RRCConnectionRequest message on Cell 2 & 3
    f_EUTRA_CheckNoAttachOn2Cells ( eutra_Cell2,
                                    eutra_Cell3,
                                    v_WaitTime,
                                    "Step 23: RRCConnectionRequest message received on Cell 2 or 3");

    f_EUTRA_TestBody_Set ( false );

    //Switch/power off UE
    f_EUTRA_Postamble ( eutra_Cell1, E1_IDLE );
  }
}
