/******************************************************************************/
// @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-10 15:33:02 +0200 (Fri, 10 Sep 2010) $
// $Rev: 3842 $
/******************************************************************************/

module CDMA2000_CommonFunctions
{
  import from CommonDefs all;
  import from CDMA2000_CellInfo all;
  import from CDMA2000_Component all;
  import from CDMA2000_CommonDefs all;
  import from CDMA2000_Templates all;
  import from CDMA2000_ASP_TypeDefs all;
  import from CDMA2000_Constants all;
  import from CommonIratDefs all;
  import from UpperTesterFunctions all;
  import from Parameters all;
  
  //============================================================================
  /*
   * @desc      Generic function for HRPD/RTT1X Cell Configuration
   * @param     p_CellId
   * @param     p_SYSTEM_CTRL_REQ
   * @status
   */
  function f_CDMA2000_SS_CommonCellConfig(CDMA2000_CellId_Type p_CellId,
                                          template (value) CDMA2000_SYSTEM_CTRL_REQ p_SYSTEM_CTRL_REQ) runs on CDMA2000_PTC
  {
    SYS.send( p_SYSTEM_CTRL_REQ );
    if (valueof(p_SYSTEM_CTRL_REQ.Common.ControlInfo.CnfFlag) == true) {
      SYS.receive ( car_CDMA2000_CellConfig_CNF ( p_CellId ) );
    }
  }
  
  //----------------------------------------------------------------------------
  /*
   * @desc      Configures HRPD cell
   * @param     p_CellId
   * @status
   */
  function f_CreateCell_HRPD (CDMA2000_CellId_Type p_CellId) runs on CDMA2000_PTC
  {
    var template (value) CDMA2000_CellParameters_Type v_CellParameters := f_CDMA2000_CommonCellParameters_Get(p_CellId);
    var template (value) HRPD_CellParameters_Type v_HRPD_CellParameters := f_CDMA2000_HRPD_CellParameters_Get(p_CellId);
    var template (value) CDMA2000_AbsoluteCellPower_Type v_CDMA2000_AbsoluteCellPower := f_CDMA2000_CellPower_Get(p_CellId);
    f_CDMA2000_SS_CommonCellConfig (p_CellId, cas_HRPD_CellConfig_REQ (p_CellId, v_CellParameters, v_HRPD_CellParameters, v_CDMA2000_AbsoluteCellPower));
  }
  
  //----------------------------------------------------------------------------
  /*
   * @desc      Function that will be called in test cases to create a CDMA2000 cell
   * @param     p_CellId
   * @status
   */
  function f_CDMA2000CreateCell (CDMA2000_CellId_Type p_CellId) runs on CDMA2000_PTC
  {
    if (match (f_CDMA2000_Type_Get(p_CellId), typeHRPD))
      { // HRPD Cell
        f_CreateCell_HRPD (p_CellId);
      }
    else
      { // RTT1X Cell;
        // FFS
      }
    
    // Other initializations to be done here
    
  } // end of f_CDMA2000CreateCell
  
  //----------------------------------------------------------------------------
  /*
   * @desc      Function that will release one or/all configired CDMA2000 cells [HRPD and RTT1X]
   * @param     p_CellId : if individual cell ID is provided the cell with cell ID is released;
   *                       if cell non specific ID is used all configured cells will be released
   * @param     p_TimingInfo
   * @status
   */
  function f_CDMA2000_ReleaseCells (CDMA2000_CellId_Type p_CellId := cdma2000_Cell_NonSpecific, // Release all cells
                                    template (value) CDMA2000_TimingInfo_Type p_TimingInfo := cs_CDMA2000_TimingInfoNow) runs on CDMA2000_PTC
  {
    f_CDMA2000_SS_CommonCellConfig( p_CellId, cas_CDMA2000_CellRel_REQ (p_CellId,p_TimingInfo ));
  }
  
  //============================================================================
  // Function to set cell power level
  //----------------------------------------------------------------------------
  /*
   * @desc      calculate new attenuation for a cell based on the previous attenuation and the given absolute cell power;
   *            the attenuation is written back to the global TTCN-3 EUTRA_CellInfo but no configuration is performed at SS
   * @param     p_CellId
   * @param     p_NewPowerLevel   absolute (negative) value of Ior calcualted at time instance
   * @return    CDMA2000_Attenuation_Type
   * @status
   */
  function fl_CDMA2000_ChangeCellAttenuation(CDMA2000_CellId_Type p_CellId,
                                             PowerIor_Type p_NewPowerLevel) runs on CDMA2000_PTC return CDMA2000_Attenuation_Type
  {
    var CDMA2000_ReferenceCellPower_Type v_CurrentCellPower := f_CDMA2000_CellInfo_GetCellPower( p_CellId );
    var PowerIor_Type v_CurrentRefPowerLevel := v_CurrentCellPower.CellPower.PowerIor;
    var CDMA2000_Attenuation_Type v_Attenuation;
    var integer v_AttenuationValue;
    
    if (p_NewPowerLevel == tsc_NonSuitableOffCellPowerIor) {
      v_Attenuation.Off := true;
    } else {
      v_AttenuationValue := v_CurrentRefPowerLevel - p_NewPowerLevel;  // v_CurrentRefPowerLevel and p_NewPowerLevel both are negative values
      
      if (v_AttenuationValue < 0) {  // i.e. |p_NewPowerLevel| < |v_CurrentRefPowerLevel|
        FatalError (__FILE__, __LINE__, "Initial reference power has invalid value");
      } else {
        v_Attenuation.Value := v_AttenuationValue;
      }
    }
    
    v_CurrentCellPower.CellAttenuation := v_Attenuation;
    f_CDMA2000_CellInfo_SetCellPower (p_CellId, v_CurrentCellPower);
    
    return v_Attenuation;
  }
  
  //----------------------------------------------------------------------------
  
  type record CDMA2000_CellPower_Type {
    CDMA2000_CellId_Type CellId,
    PowerIor_Type NewPowerLevel
  };
  type record length(1..tsc_CDMA2000_MaxNumberOfCells) of CDMA2000_CellPower_Type CDMA2000_CellPowerList_Type;  /* used together with f_CDMA2000_SetCellPowerList */
  
  template (value) CDMA2000_CellPower_Type cs_CDMA2000_CellPower(CDMA2000_CellId_Type p_CellId,
                                                                 PowerIor_Type p_NewPowerLevel) :=
  {
    CellId := p_CellId,
    NewPowerLevel := p_NewPowerLevel
  };
  
  /*
   * @desc      to configure power of several cells in one go
   * @param     p_CellPowerList
   * @param     p_TimingInfo
   * @status
   */
  function f_CDMA2000_SetCellPowerList (template (value) CDMA2000_CellPowerList_Type p_CellPowerList,
                                        template (value) CDMA2000_TimingInfo_Type p_TimingInfo := cs_CDMA2000_TimingInfoNow) runs on CDMA2000_PTC
  {
    var integer i;
    var CDMA2000_CellPower_Type v_CellPower;
    var CDMA2000_CellAttenuationList_Type v_CellAttenuationList;
    
    for (i:=0; i<lengthof(p_CellPowerList); i:=i+1) {
      v_CellPower := valueof(p_CellPowerList[i]);   // valueof cannot be avoided here
      v_CellAttenuationList[i].CellId := v_CellPower.CellId;
      v_CellAttenuationList[i].Attenuation := fl_CDMA2000_ChangeCellAttenuation(v_CellPower.CellId, v_CellPower.NewPowerLevel);
    }
    
    SYS.send( cas_CDMA2000_CellConfig_Power_REQ ( v_CellAttenuationList, p_TimingInfo ) );
    SYS.receive ( car_CDMA2000_CellConfig_Power_CNF ); //TBD ASP can be car_CDMA2000_CellConfig_Power_CNF
  }
  
  //----------------------------------------------------------------------------
  /*
   * @desc      Sets the cell power attenuation and stores the value in the EUTRA_CellInfo
   * @param     p_CellId
   * @param     p_NewPowerLevel   absolute (negative) value as specified in the test prose
   * @param     p_TimingInfo
   * @status
   */
  function f_CDMA2000_SetCellPower (CDMA2000_CellId_Type p_CellId,
                                    PowerIor_Type p_NewPowerLevel,
                                    template (value) CDMA2000_TimingInfo_Type p_TimingInfo := cs_CDMA2000_TimingInfoNow) runs on CDMA2000_PTC
  {
    var template (value) CDMA2000_CellPowerList_Type v_CellPowerList := { cs_CDMA2000_CellPower(p_CellId, p_NewPowerLevel) };
    f_CDMA2000_SetCellPowerList ( v_CellPowerList, p_TimingInfo );
  }
  //----------------------------------------------------------------------------
  /*
   * @desc     Performs a Registration procedure on an HRPD cell as defined in clause 10.4.1.1 of 36.523-3
   * @param     p_CellId
   * @status
   */
  function f_CDMA2000_RegisterHRPDCell (CDMA2000_CellId_Type p_CellId) runs on CDMA2000_PTC
  {
    timer t_Watchdog := tsc_WatchDogDef ;              // Local wait Timer
    t_Watchdog.start;
    SYSCMD_IND.send (cas_CDMA2000_SYSTEM_CMD_HRPD(p_CellId,
                                                  -, // timing info now
                                                  cs_HRPD_SysCmd_RegAndDefBearerEst_Def));
    SYSCMD_IND.receive(car_CDMA2000_SYSTEM_IND_HRPD (p_CellId,
                                                     -, // routing info none
                                                     -, // timing info any
                                                     cr_SysInd_InitialAccesProbRcvd));
    SYSCMD_IND.receive(car_CDMA2000_SYSTEM_IND_HRPD (p_CellId,
                                                     -, // routing info none
                                                     -, // timing info any
                                                     cr_SysInd_RegAndDef(cr_RegAndDefBearerEstInd_Def)));
    t_Watchdog.stop;
  }
  //----------------------------------------------------------------------------
  /*
   * @desc     Performs a Registration procedure on an HRPD cell as defined in clause 10.4.1.1 of 36.523-3
   * @param     p_CellId
   * @param     p_WaitTimer
   * @status
   */
  function f_CDMA2000_CheckUEDoesNotCamponHRPDCell (CDMA2000_CellId_Type p_CellId,
                                                    float p_WaitTimer :=tsc_WatchDogDef) runs on CDMA2000_PTC
  {
    timer t_Watchdog := p_WaitTimer ;              // Local wait Timer
    t_Watchdog.start;
    SYSCMD_IND.send (cas_CDMA2000_SYSTEM_CMD_HRPD(p_CellId,
                                                  -, // timing info now
                                                  cs_ConfigReportInitAccesProbe));
    alt {
      []SYSCMD_IND.receive(car_CDMA2000_SYSTEM_IND_HRPD (p_CellId,
                                                         -, // routing info none
                                                         -, // timing info any
                                                         cr_SysInd_InitialAccesProbRcvd))
        {
          t_Watchdog.stop;
          f_CDMA2000_SetVerdictFailOrInconc(__FILE__, __LINE__, "UE is sending Access probe");
        }
      []t_Watchdog.timeout {
        f_CDMA2000_PreliminaryPass(__FILE__, __LINE__, "UE did not send Access probe");
        
      }
    };
    
    
  }
  function f_CDMA2000_Send_IR_SysInfoToEUTRA (CDMA2000_CellId_Type p_CellId) runs on CDMA2000_PTC
  {
    var CDMA2000_CommonCellInfo_Type v_CommonCellInfo := f_CDMA2000_CommonCellInfo_Get( p_CellId );
    
    f_SendIRATCoOrd ( EUTRA, cms_IRAT_SysInfo ( cs_CoOrdCDMA2000_SysInfoOneCell(f_CDMA2000_IR_InitSingleSysInfo ( v_CommonCellInfo ))) );
  }
  function f_CDMA2000_DetachOnSwitchOff(CDMA2000_CellId_Type p_CellId,
                                        HRPD_UE_InitStateType   p_InitState :=tsc_HRPD_UE_InitState_Active) runs on CDMA2000_PTC
  {
    if (pc_SwitchOnOff) // The UE can actually be switched off
      {
        f_UT_SwitchOffUE (UT, false);
        select (p_InitState){
          case (dormant) // expect Access probe and DefaultBearerRelDetachInd_Type
            {
              SYSCMD_IND.send (cas_CDMA2000_SYSTEM_CMD_HRPD(p_CellId,
                                                            -, // timing info now
                                                            cs_DetachOnSwitchOff(p_InitState)));
              SYSCMD_IND.receive(car_CDMA2000_SYSTEM_IND_HRPD (p_CellId,
                                                               -, // routing info none
                                                               -, // timing info any
                                                               cr_SysInd_InitialAccesProbRcvd));
              SYSCMD_IND.receive(car_CDMA2000_SYSTEM_IND_HRPD (p_CellId,
                                                               -, // routing info none
                                                               -, // timing info any
                                                               cr_DetachOnSwitchOffInd));
            }
          case (active_Connected, preregister) //expect  DefaultBearerRelDetachInd_Type
            {
              SYSCMD_IND.send (cas_CDMA2000_SYSTEM_CMD_HRPD(p_CellId,
                                                            -, // timing info now
                                                            cs_DetachOnSwitchOff(p_InitState)));
              SYSCMD_IND.receive(car_CDMA2000_SYSTEM_IND_HRPD (p_CellId,
                                                               -, // routing info none
                                                               -, // timing info any
                                                               cr_DetachOnSwitchOffInd));
            }
          case else  // null state
                 {
                   //do nothing
                 }
        } // end of switch
      }     else
      {// The power must be removed from the UE
        f_UT_PowerOffUE (UT);
      }
    
  }// end of f_CDMA2000_DetachOnSwitchOff
  
  function f_CDMA2000_Postamble (CDMA2000_CellId_Type p_CellId,
                              HRPD_UE_InitStateType   p_InitState :=tsc_HRPD_UE_InitState_Active) runs on CDMA2000_PTC
  {
    f_CDMA2000_DetachOnSwitchOff(p_CellId,   p_InitState);
    f_CDMA2000_ReleaseCells(); //Delete all configured CDMA2000 cells
  }// end of f_CDMA2000_DetachOnSwitchOff
  
} // End of module

