/******************************************************************************/
// @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-04-29 11:49:29 +0200 (Thu, 29 Apr 2010) $
// $Rev: 2896 $
/******************************************************************************/

module GERAN_CapabilityFunctions {

  //----------------------------------------------------------------------
  // Imports
  //----------------------------------------------------------------------
  
  import from CommonDefs all;
  
  import from NAS_CommonTypeDefs all;
  import from NAS_CommonTemplates all;
  import from NAS_24008TypeDefs all;
  import from NAS_24008Templates all;

  //----------------------------------------------------------------------
  // Templates
  //----------------------------------------------------------------------
  
  template MS_Clsmk3 cdr_MSCLSMK3_EutraCheck modifies cr_MSCLSMK3_Any :=
  { /* @status    APPROVED */
    eutraFDDSupport := ?,
    eutraTDDSupport := ?
  };

  template MS_RadioAccessCap cr_MSRadioAccessCapEutraCheck :=
  { /* @status    APPROVED */
    accessTechType := complement ('1111'B),
    singleAccess   := cr_SingleAccessCapAny,  // only present if accessTechType != 1111
    addLength      := omit,   // only present if accessTechType = 1111
    addAccess      := omit,   // only present if accessTechType = 1111
    sparebits      := *
  };
  

  //----------------------------------------------------------------------
  // Functions
  //----------------------------------------------------------------------
  /*
   * @desc      To be called from the EUTRA PTC to encode the MS Radio Access Capability message
   * @param     p_Octetstring  ..  container which is to be decoded
   * @return    boolean        ..  indicates if match/check has been successful
   * @status    APPROVED
   */
  function f_DecodeAndCheckMsRadioAccessCap ( octetstring p_Octetstring ) return boolean
  { // From 36.331 cl. 6.3.6
    // The encoding of UE capabilities is formatted as 'V' and is coded in the same way as
    // the value part in the MS Radio Access Capability information element in TS 36.306 [5]
    
    // According to 36.523-1 cl. 8.5.4.1
    // CSN.1 decoding shall be successfull and the contents shall indicate that E-UTRA FDD
    // or EUTRA TDD or both is supported. Other values are not checked.
    
    var MS_RadioAccessCap v_Received_MS_RadioAccessCap_Container;
    var bitstring v_MS_RadioAccessCap_Bitstring := oct2bit (p_Octetstring);
    var boolean v_CheckResult := false;
    var integer v_DecResult := decvalue ( v_MS_RadioAccessCap_Bitstring, v_Received_MS_RadioAccessCap_Container );
    
    if ( v_DecResult != 0 ) {
      FatalError(__FILE__, __LINE__, "UE GERAN MS Radio Access Cap cannot be decoded");
    }
    if ( match ( v_Received_MS_RadioAccessCap_Container, cr_MSRadioAccessCapEutraCheck ) ) {
      if ((v_Received_MS_RadioAccessCap_Container.singleAccess.eutraFDD == '1'B) or (v_Received_MS_RadioAccessCap_Container.singleAccess.eutraTDD == '1'B)) {
        v_CheckResult := true;
      }
    }
    return v_CheckResult;
  }

  /*
   * @desc      To be called from the EUTRA PTC to encode the Mobile Station Classmark 2 & 3 messages
   * @param     p_Octetstring  ..  container which is to be decoded
   * @return    B2_Type        ..  indicates if match/check has been succesful
   * @status    APPROVED
   */
  function f_DecodeAndCheckMsClassmark ( octetstring p_Octetstring ) return B2_Type
  {
    var MS_Clsmk2 v_Received_MS_Clsmk2_Container;
    var MS_Clsmk3 v_Received_MS_Clsmk3_Container;
    var O5_Type v_MS_Clsmk2_OctetString;
    var octetstring v_MS_Clsmk3_OctetString;
    var bitstring v_MS_Clsmk2_Bitstring;
    var bitstring v_Received_MS_Clsmk3_Bitstring;
    var integer v_MS_Clsmk3_DecResult;
    var integer v_MS_Clsmk2_DecResult;
    var B1_Type v_MS_Clsmk2_Result := '0'B;        // 0 means false (MS_Clsmk2 capabilities are not correctly reported)
    var B1_Type v_MS_Clsmk3_Result := '0'B;        // 0 means false (MS_Clsmk3 capabilities are not correctly reported)
    var integer v_OctetstringLength := lengthof ( p_Octetstring );    /* The octet string contains the concatenated string of the Mobile Station Classmark 2
                                                                       * and Mobile Station Classmark 3.
                                                                       * The first 5 octets correspond to Mobile Station Classmark 2
                                                                       * and the following octets correspond to Mobile Station Classmark 3.*/
    
    if ( v_OctetstringLength < 6 ) {
      FatalError(__FILE__, __LINE__, "Not enough octets in container");
    }
    else {
      v_MS_Clsmk2_OctetString := substr ( p_Octetstring, 0, 5);
      v_MS_Clsmk3_OctetString := substr ( p_Octetstring, 5, v_OctetstringLength - 5 );
    }
    
    /* Mobile Station Classmark 2:
     *  36.523-1 cl. 8.5.4.1: First byte is 33H. Second byte is 3. Third, Fourth and Fith bytes are ignored.
     *  36.331 cl. 6.3.6: The Mobile Station Classmark 2 is formatted as 'TLV' and is coded in the
     *                    same way as the Mobile Station Classmark 2 information element in TS 24.008 [49].
     *                    The first octet is the Mobile station classmark 2 IEI and its value shall be set to 33H.
     *                    The second octet is the Length of mobile station classmark 2 and its value shall be set to 3.
     *                    The octet 3 contains the first octet of the value part of the Mobile Station Classmark 2 information element.
     *                    The octet 4 contains the second octet of the value part of the Mobile Station Classmark 2 information element and so on.
     *                    For each of these octets, the first/ leftmost/ most significant bit of the octet contains b8 of
     *                    the corresponding octet of the Mobile Station Classmark 2. */
    v_MS_Clsmk2_Bitstring := oct2bit ( v_MS_Clsmk2_OctetString );
    v_MS_Clsmk2_DecResult := decvalue ( v_MS_Clsmk2_Bitstring, v_Received_MS_Clsmk2_Container );
    
    if ( v_MS_Clsmk2_DecResult != 0 ) {
      FatalError(__FILE__, __LINE__, "UE GERAN Classmark 2 cannot be decoded");
    }
    if ( match ( v_Received_MS_Clsmk2_Container, cr_MS_Clsmk2_Any_tlv ) ) {
      v_MS_Clsmk2_Result := '1'B;
    }
    
    /* Mobile Station Classmark 3:
     * 36.523-1 cl. 8.5.4.1: CSN.1 decoding shall be successfull and the contents shall indicate that E-UTRA FDD or EUTRA TDD
     *                       or both is supported. Other values are not checked.
     * 36.331 cl. 6.3.6: The Mobile Station Classmark 3 is formatted as 'V' and is coded in the same way as the value part
     *                   in the Mobile station classmark 3 information element in TS 24.008 [49].
     *                   The sixth octet of this octet string contains octet 1 of the value part of Mobile station classmark 3,
     *                   the seventh of octet of this octet string contains octet 2 of the value part of Mobile station classmark 3 and so on. */
    v_Received_MS_Clsmk3_Bitstring := oct2bit ( v_MS_Clsmk3_OctetString );
    v_MS_Clsmk3_DecResult := decvalue ( v_Received_MS_Clsmk3_Bitstring, v_Received_MS_Clsmk3_Container );
    if ( v_MS_Clsmk3_DecResult != 0 ) {
      FatalError(__FILE__, __LINE__, "UE GERAN Classmark 3 cannot be decoded");
    }
    if ( match ( v_Received_MS_Clsmk3_Container, cdr_MSCLSMK3_EutraCheck ) ) {
      v_MS_Clsmk3_Result := '1'B;
    }
    
    //* @desc Return result of GERAN CS check
    return v_MS_Clsmk2_Result & v_MS_Clsmk3_Result;
  }
}
