/******************************************************************************/
// @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.
//   (c) 2023, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC).
//   All rights reserved.
// @version: IWD_23wk37
// $Date: 2022-06-15 13:04:40 +0200 (Wed, 15 Jun 2022) $
// $Rev: 33645 $
/******************************************************************************/

module NasEmu_Common4G5G {
  import from CommonDefs all;
  import from NAS_CommonTypeDefs all;

  //****************************************************************************
  // NAS emulation: Common Control ASPs
  //----------------------------------------------------------------------------
  type record NasCtrlReqAspControlInfo_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    boolean CnfFlag
  };

  type record NasCtrlReqAspCommonPart_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    NasCtrlReqAspControlInfo_Type  ControlInfo
  };

  type record NasCtrlCnfAspCommonPart_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    // place holder only
  };

  type record NasCountInfo_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    NasCount_Type             UL  optional,     /* UL NAS COUNT is the value corresponding to the latest PDU sent by the UE;
                                                   acc. 24.301 cl. 4.4.3.1 at the UE the NAS COUNT is initialised with 0;
                                                   => in TTCN (NAS emulation) NAS COUNT is initialised with its max. value;
                                                   omit: keep as it is */
    NasCount_Type             DL  optional      /* DL NAS COUNT is the value corresponding to the latest PDU sent to the UE;
                                                   acc. 24.301 cl. 4.4.3.1 at the UE the NAS COUNT is initialised with 0;
                                                   => in TTCN (NAS emulation) NAS COUNT is initialised with its max. value;
                                                   omit: keep as it is */
  };

  type union NAS_CountReq_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    Null_Type                 Get,
    NasCountInfo_Type         Set
  };

  type union NAS_CountCnf_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    NasCountInfo_Type         Get,
    Null_Type                 Set
  };

  type union NasCtrlConfirm_Type { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    Null_Type                 Security,
    NAS_CountCnf_Type         NasCount
  };

  //****************************************************************************
  // NAS emulation: Local definitions
  //----------------------------------------------------------------------------

  const boolean tsc_NasEmu_TerminateOnError := true;        /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */

  //****************************************************************************
  // NAS emulation: global information
  //----------------------------------------------------------------------------

  /*
   * @desc      initialise NAS COUNT
   * @return    NasCount_Type .. initial NAS COUNT
   *            Note: NAS COUNT for both UL and DL is the value of the last PDU being receive from or send to the UE;
   *                  => as for both sides the initial value in a PDU shall be 0 (24.301 cl. 4.4.3.1)
   *                     the internal value needs to be set to the maximum value (i.e. when this is incremented it results in 0)
   * @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN)
   */
  function f_NasCountInit() return NasCount_Type
  {
    var integer v_CountValue := (65536 * 256) - 1;
    return int2oct(v_CountValue, 4);
  }

  //****************************************************************************
  // NAS emulation: Configuration primitives
  //----------------------------------------------------------------------------

  template (value) NasCtrlCnfAspCommonPart_Type cs_NasCtrlCnfAspCommonPart :=
  { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN) */
    // place holder only
  };

  template (value) NasCtrlReqAspCommonPart_Type cs_NasCtrlReqAspCommonPart(boolean p_CnfFlag := true) :=
  { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS) */
    ControlInfo := {
      CnfFlag := p_CnfFlag
    }
  };

  template (present) NasCtrlCnfAspCommonPart_Type cr_NasCtrlCnfAspCommonPart :=
  { /* @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS) */
    // place holder only
  };

  //****************************************************************************
  // NAS emulation: Error Handling
  //----------------------------------------------------------------------------
  /*
   * @desc      wrapper to allow controlled termination of the NAS emu
   * @param     p_FileName
   * @param     p_LineNo
   * @param     p_Msg
   * @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN)
   */
  function f_NasEmulationError(charstring p_FileName,
                               LineNo_Type p_LineNo,
                               charstring p_Msg)
  {
    var boolean v_TerminateOnError := tsc_NasEmu_TerminateOnError;

    if (v_TerminateOnError) {
      f_SetVerdictInconc(p_FileName, p_LineNo, p_Msg);
    } else {
      f_ErrorLog(p_FileName, p_LineNo, p_Msg);
    }
  }

  //****************************************************************************
  // NAS emulation: auxiliary functions
  //----------------------------------------------------------------------------
  /*
   * @desc      get the normal (long) SN from the COUNT
   * @param     p_Count
   * @return    NAS_SequenceNumber
   * @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN)
   */
  function f_NasSecurity_ExtractSNfromCOUNT(NasCount_Type p_Count) return NAS_SequenceNumber
  {
    return int2oct(oct2int(p_Count) mod 256, 1);
  };

  //----------------------------------------------------------------------------
  /*
   * @desc      increment COUNT (in DL)
   * @param     p_Count
   * @return    NasCount_Type  .. incremented COUNT
   * @status    APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, MCX, NBIOT, NR5GC, NR5GC_IRAT, POS, UTRAN)
   */
  function f_NasSecurity_IncrementCOUNT(NasCount_Type p_Count) return NasCount_Type
  {
    var integer v_CountValue := oct2int(p_Count);
    v_CountValue := (v_CountValue + 1) mod (65536 * 256);    // the 8 most significant bits are 0 (24.301 cl. 4.4.3.1)
    return int2oct(v_CountValue, 4);
  };
  
  //----------------------------------------------------------------------------
  type record NASEmu_CoOrd_REQ {  /* @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */
    octetstring        IntegrityProtectedOctets,
    integer            SequenceNumber
  };

  type record NASEmu_CoOrd_CNF {              /* @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */
    MessageAuthenticationCode MAC
  };

  template (value) NASEmu_CoOrd_REQ cs_NASEmu_CoOrd_REQ (octetstring p_IntegrityProtectedOctets, integer p_SequenceNumber) := {
    /* @status    APPROVED (NR5GC_IRAT) */
    IntegrityProtectedOctets    := p_IntegrityProtectedOctets,
    SequenceNumber              := p_SequenceNumber
  };
   
  template (present) NASEmu_CoOrd_REQ cr_NASEmu_CoOrd_REQ  := { /* @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */
    IntegrityProtectedOctets    := ?,
    SequenceNumber              := ?
  };

  template (value) NASEmu_CoOrd_CNF cs_NASEmu_CoOrd_CNF (MessageAuthenticationCode p_MAC) := { /* @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */
    MAC := p_MAC
  };
  
  template (present) NASEmu_CoOrd_CNF cr_NASEmu_CoOrd_CNF := { /* @status    APPROVED (NR5GC_IRAT) */
    MAC := ?
  };
  
  type port NASEMU4G_CO_ORD_PORT message {   /* @status    APPROVED (NR5GC_IRAT) */
    out NASEmu_CoOrd_REQ;
    in NASEmu_CoOrd_CNF;
  };

  type port NASEMU5G_CO_ORD_PORT message {    /* @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */
    out NASEmu_CoOrd_CNF;
    in NASEmu_CoOrd_REQ;
  };

}
