/******************************************************************************/
// @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: 2023-09-14 09:54:06 +0200 (Thu, 14 Sep 2023) $
// $Rev: 37128 $
/******************************************************************************/

module NG_NASTemplateFunctions {
  import from CommonDefs all;
  import from NAS_CommonTypeDefs all;
  import from NG_NAS_MsgContainers all;
  import from NG_NAS_TypeDefs all;
  import from NG_NAS_Templates all;
  import from NG_NAS_Common all;
  import from NAS_CommonTemplates all;
  import from NG_NAS_SecurityFunctions all;
  import from NAS_AuthenticationCommon all;
  import from NAS_AuxiliaryDefsAndFunctions all;
  import from CommonIP all;
  import from NAS_5GC_Parameters all;
  import from Parameters all;
  import from NR_Parameters all;
  import from EAP_TypeDefs all;
  import from TestcaseProperties all;

  //----------------------------------------------------------------------------
  /*
   * @desc      check the REGISTRATION REQUEST
   * @param     p_GMM_MobilityInfo  (by reference)
   * @param     p_ReceivedMsgs
   * @param     p_RegType
   * @param     p_GUTI              (default value: ?)
   * @param     p_KeySetId          (default value: ?)
   * @param     p_Tsc               (default value: ?)
   * @param     p_NonCurrentKSI     (default value: *)
   * @param     p_GMM_Cap           (default value: *)
   * @param     p_UESecurityCap     (default value: *)
   * @param     p_ReqNSSAI          (default value: *)
   * @param     p_TAI               (default value: *)
   * @param     p_UE_NetworkCap     (default value: *)
   * @param     p_ULDataStatus      (default value: *)
   * @param     p_PDU_SessionStatus (default value: *)
   * @param     p_MICO_Ind          (default value: *)
   * @param     p_UE_Status         (default value: *)
   * @param     p_AddGUTI           (default value: *)
   * @param     p_AllowedPDU_SessionStatus (default value: *)
   * @param     p_UE_UsageSetting   (default value: *)
   * @param     p_DRXparam          (default value: *)
   * @param     p_EPSMsg            (default value: *)
   * @param     p_LADN_Ind          (default value: *)
   * @param     p_Payload           (default value: *)
   * @param     p_ContainerType     (default value: cr_PayloadContainerType ('0101'B) ifpresent
   * @param
   * @param     p_NetworkSlicingInd (default value: *)
   * @param     p_NG_UpdateType     (default value: *)
   * @param     p_MS_Clsmk2         (default value: *)
   * @param     p_SupportedCodecs   (default value: *)
   * @param     p_EPS_BearerContextStatus (default value: *)
   * @param     p_ExtdDRXParams     (default value: *)
   * @param     p_T3324             (default value: *)
   * @param     p_UERadioCapId      (default value: *)
   * @param     p_MappedNSSAI       (default value: *)
   * @param     p_AddInfoRequest    (default value: *)
   * @param     p_WUSAssistInfo     (default value: *)
   * @param     p_N5GCInd           (default value: *)
   * @param     p_NB_N1ModeDRXParams (default value: *)
   * @param     p_UeRequestType (default value: *)
   * @param     p_PagingRestrict (default value: *)
   * @param     p_ServiceLvlAA (default value: *)
   * @param     p_NId (default value: *)
   * @param     p_MSPLMNwDisasterCondition (default value: *)
   * @param     p_RequestedPEIPS_AssistInfo (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_RegistrationReqMsg(out GMM_MobilityInfo_Type p_GMM_MobilityInfo,
                                         NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                         template (present) TypeOfRegistration_Type p_RegType,
                                         template (present) NG_MobileIdentity p_GUTI := ?,
                                         template (present) NAS_KsiValue p_KeySetId := ?,
                                         template (present) B1_Type p_Tsc := ?,
                                         template NAS_KeySetIdentifier p_NonCurrentKSI := *,
                                         template NG_GMM_Cap p_GMM_Cap := *,
                                         template NG_UE_SecurityCapability p_UESecurityCap := *,
                                         template NSSAI p_ReqNSSAI := *,
                                         template NG_TrackingAreaId p_TAI := *,
                                         template UE_NetworkCap p_UE_NetworkCap := *,
                                         template ULDataStatus p_ULDataStatus := *,
                                         template PDU_SessionStatus p_PDU_SessionStatus := *,
                                         template MICO_Ind p_MICO_Ind := *,
                                         template UE_Status p_UE_Status := *,
                                         template NG_MobileIdentity p_AddGUTI := *,
                                         template AllowedPDU_SessionStatus p_AllowedPDU_SessionStatus := *,
                                         template UE_UsageSetting p_UE_UsageSetting := *,
                                         template NG_DRXparameter p_DRXparam := *,
                                         template EPS_MessageContainer p_EPSMsg := *,
                                         template LADN_Ind p_LADN_Ind := *,
                                         template PayloadContainer p_Payload := *,
                                         template PayloadContainerType p_ContainerType := cr_PayloadContainerType ('0101'B, '8'H) ifpresent, // @sic R5w190113, R5-216156 sic@
                                         template NetworkSlicingInd p_NetworkSlicingInd := *,
                                         template NG_UpdateType p_NG_UpdateType := *,
                                         template MS_Clsmk2 p_MS_Clsmk2 := *,
                                         template CodecList p_SupportedCodecs := *,
                                         template EPS_BearerContextStatus p_EPS_BearerContextStatus := *, // @sic R5s190543 sic@
                                         template ExtdDRXParams p_ExtdDRXParams := *,
                                         template GPRS_Timer3 p_T3324 := *,
                                         template UERadioCapId p_UERadioCapId := *,
                                         template MappedNSSAI p_MappedNSSAI := *,
                                         template AddInfoRequest p_AddInfoRequest := *,
                                         template WUSAssistInfo p_WUSAssistInfo := *,
                                         template N5GCInd p_N5GCInd := *,
                                         template NB_N1ModeDRXParams p_NB_N1ModeDRXParams := *,
                                         template UE_RequestType p_UeRequestType := *,
                                         template NG_PagingRestriction p_PagingRestrict := *,
                                         template ServiceLvlAAContainer p_ServiceLvlAA := *,
                                         template NID p_NId := *,
                                         template PLMN_IdIE p_MSPLMNwDisasterCondition := *,
                                         template PEIPS_AssistInfo p_RequestedPEIPS_AssistInfo := *,
                                         template GPRS_Timer3 p_T3512 := *) return boolean
  {
    var NG_NAS_UL_Message_Type v_NASMsg;
    var boolean v_Result := false;
    var template (present) RegistrationType v_RegistrationType;
    
    v_NASMsg := p_ReceivedMsgs.Msg;

    if (isvalue(p_RegType)) { // @sic R5s200436 sic@
      select (valueof(p_RegType)) { // @sic R5-201143 sic@
        case (Mobility) {
          v_RegistrationType := cr_RegistrationType(tsc_NG_RegistrationMobility, ?);
        }
        case (Periodic) {
          v_RegistrationType :=  cr_RegistrationType(tsc_NG_RegistrationPeriodic, ?);
        }
        case (Emergency) {
          v_RegistrationType :=  cr_RegistrationType(tsc_NG_RegistrationEmergency, '1'B);
        }
        case (SNPN_Onboarding) {  // @sic R5-233987 sic@
          v_RegistrationType :=  cr_RegistrationType(tsc_NG_RegistrationSNPN, ?);
        }
        case else {
          v_RegistrationType :=  cr_RegistrationType(tsc_NG_RegistrationInitial, ?);
          // Check the 'first' message to make sure it only includes cleartext IEs
          if (not match (v_NASMsg, cr_NG_REGISTRATION_REQUEST(v_RegistrationType, // @sic R5-196637 sic@
                                                            p_KeySetId,
                                                            p_Tsc,
                                                            p_GUTI,
                                                            omit,
                                                            omit,
                                                            p_UESecurityCap,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            p_UE_Status, // default *
                                                            p_AddGUTI,   // default *
                                                            omit,
                                                            omit,
                                                            omit,
                                                            p_EPSMsg,    // default *
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,  // @sic R5s201387 Baseline Moving sic@
                                                            omit,  // @sic R5s201387 Baseline Moving sic@
                                                            *,
                                                            omit,  // @sic R5s201387 Baseline Moving sic@
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,
                                                            omit,  // @sic R5s221179 Baseline Moving sic@
                                                            omit,  // @sic R5s221179 Baseline Moving sic@
                                                            omit,  // @sic R5s221179 Baseline Moving sic@
                                                            omit,  // @sic R5s221179 Baseline Moving sic@
                                                            omit,  // @sic R5s221179 Baseline Moving sic@
                                                            omit,  // @sic R5s230533 sic@
                                                            omit))) {
             FatalError(__FILE__, __LINE__, "Initial Registration Req included non-cleartext IEs");
           }
         } // @sic R5s200309 sic@
       }
     } else { // @sic R5s200436 sic@
       v_RegistrationType :=  cr_RegistrationType((tsc_NG_RegistrationInitial, tsc_NG_RegistrationMobility), ?);
     }
     if (isvalue(p_ReceivedMsgs.PiggybackedPduList)) {
         /* this will be the un-ciphered message from the NAS Container
            if the SS couldn't decipher the message (because it doesn't have the security context, e.g. at the start of a test)
            this field will be set to omit
         */
       v_NASMsg := valueof(p_ReceivedMsgs.PiggybackedPduList[0].Msg);
     }

    // Now check the full message, if present, against all expected values
    if (match (v_NASMsg, cr_NG_REGISTRATION_REQUEST(v_RegistrationType, // @sic R5-196637 sic@
                                                    p_KeySetId,
                                                    p_Tsc,
                                                    p_GUTI,
                                                    p_NonCurrentKSI,
                                                    p_GMM_Cap,
                                                    p_UESecurityCap,
                                                    p_ReqNSSAI,
                                                    p_TAI,
                                                    p_UE_NetworkCap,
                                                    p_ULDataStatus,
                                                    p_PDU_SessionStatus,
                                                    p_MICO_Ind,
                                                    p_UE_Status,
                                                    p_AddGUTI,
                                                    p_AllowedPDU_SessionStatus,
                                                    p_UE_UsageSetting,
                                                    p_DRXparam,
                                                    p_EPSMsg,
                                                    p_LADN_Ind,
                                                    p_ContainerType,
                                                    p_Payload,
                                                    p_NetworkSlicingInd,
                                                    p_NG_UpdateType,
                                                    p_MS_Clsmk2,     // @sic R5s201387 Baseline Moving sic@
                                                    p_SupportedCodecs,  // @sic R5s201387 Baseline Moving sic@
                                                    p_EPS_BearerContextStatus,
                                                    *,
                                                    p_ExtdDRXParams, // @sic R5s201387 Baseline Moving sic@
                                                    p_T3324,
                                                    p_UERadioCapId,
                                                    p_MappedNSSAI,
                                                    p_AddInfoRequest,
                                                    p_WUSAssistInfo,
                                                    p_N5GCInd,
                                                    p_NB_N1ModeDRXParams,
                                                    p_UeRequestType,  // @sic R5s221179 Baseline Moving sic@
                                                    p_PagingRestrict,
                                                    p_ServiceLvlAA,
                                                    p_NId,
                                                    p_MSPLMNwDisasterCondition,
                                                    p_RequestedPEIPS_AssistInfo,
                                                    p_T3512))) {    //  @sic R5s230533 sic@
      v_Result := true;
    }
    // Finally, store the values received
    p_GMM_MobilityInfo.Guti := v_NASMsg.registration_Request.ngMobileId;
    if (ispresent(v_NASMsg.registration_Request.gmmCapability)) {
      p_GMM_MobilityInfo.GMMCap := v_NASMsg.registration_Request.gmmCapability;
    } else {
      p_GMM_MobilityInfo.GMMCap := omit;
    }
    if (ispresent(v_NASMsg.registration_Request.ueSecurityCapability)) {
      p_GMM_MobilityInfo.UECap := v_NASMsg.registration_Request.ueSecurityCapability;
    } else {
      p_GMM_MobilityInfo.UECap := omit;
    }
    if (ispresent(v_NASMsg.registration_Request.s1_UE_Capability)) { // @sic R5s190285 sic@
      p_GMM_MobilityInfo.S1NwkCap := v_NASMsg.registration_Request.s1_UE_Capability;
    } else {
      p_GMM_MobilityInfo.S1NwkCap := omit;
    }
    if (ispresent(v_NASMsg.registration_Request.pduSessionStatus)) {
      p_GMM_MobilityInfo.SessionStatus := v_NASMsg.registration_Request.pduSessionStatus;
    } else {
      p_GMM_MobilityInfo.SessionStatus := omit;
    }
    if (ispresent(v_NASMsg.registration_Request.epsBearerContextStatus)) { // @sic R5-206426 sic@
      p_GMM_MobilityInfo.EPSBearerStatus := v_NASMsg.registration_Request.epsBearerContextStatus;
    } else {
      p_GMM_MobilityInfo.EPSBearerStatus := omit;
    }
    if (ispresent(v_NASMsg.registration_Request.ueRadioCapabilityId)) { // @sic R5-206419 sic@
      p_GMM_MobilityInfo.UERadioCapId := v_NASMsg.registration_Request.ueRadioCapabilityId;
    } else {
      p_GMM_MobilityInfo.UERadioCapId := omit;
    }
    return v_Result;
  }

  /*
   * @desc      build the REGISTRATION ACCEPT
   * @param     p_RegType
   * @param     p_GMM_MobilityInfo
   * @param     p_GUTI
   * @param     p_TAIList
   * @param     p_EPLMNs            (default value: omit)
   * @param     p_AllowedNSSAI      (default value: cs_NSSAI_Allowed_Def)
   * @param     p_RejectedNSSAI     (default value: omit)
   * @param     p_ConfiguredNSSAI   (default value: omit)
   * @param     p_NwkFeatureSupport (default value: cs_NG_NetworkFeatureSupport_Def)
   * @param     p_PDU_SessionStatus (default value: omit)
   * @param     p_PDU_SessionReactResult (default value: omit)
   * @param     p_PDU_SessionReactError (default value: omit)
   * @param     p_LADN_Info         (default value: omit)
   * @param     p_MICO_Ind          (default value: omit)
   * @param     p_NetworkSlicingInd (default value: omit)
   * @param     p_SAIList           (default value: omit)
   * @param     p_T3512             (default value: omit)
   * @param     p_Non3GPPDereg      (default value: omit)
   * @param     p_T3502             (default value: omit)
   * @param     p_EmergNumList      (default value: omit)
   * @param     p_ExtdEmergNumList  (default value: omit)
   * @param     p_SOR               (default value: omit)
   * @param     p_EAP               (default value: omit)
   * @param     p_InclusionModeNSSAI (default value: omit)
   * @param     p_AccessCatDefinition (default value: omit)
   * @param     p_NG_DRXparameter   (default value: omit)
   * @param     p_Non3GPP_NW_ProvidedPolicies (default value: omit)
   * @param     p_EPS_BearerContextStatus (default value: omit)
   * @param     p_Access            (default value: Access_3GPP)
   * @param     p_SMSOverNAS        (default value: '0'B)
   * @param     p_EmergencyRegistered (default value: '0'B)
   * @param     p_NssaaPerformed    (default value: '0'B)
   * @param     p_NegotiatedExtdDRXParams (default value: omit)
   * @param     p_T3447             (default value: omit)
   * @param     p_T3448             (default value: omit)
   * @param     p_T3324             (default value: omit)
   * @param     p_UERadioCapId      (default value: omit)
   * @param     p_UERadioCapIdDeletion (default value: omit)
   * @param     p_PendingNSSAI      (default value: omit)
   * @param     p_CipheringKeyData  (default value: omit)
   * @param     p_CAGInfoList       (default value: omit)
   * @param     p_TruncatedS_TMSIConfig (default value: omit)
   * @param     p_WUSAssistInfo     (default value: omit)
   * @param     p_NB_N1ModeDRXParams (default value: omit)
   * @param     p_ExtdRejectedNSSAI (default value: omit)
   * @param     p_ServiceLvlAA      (default value: omit)
   * @param     p_NegotiatedPEIPS_AssistInfo (default value: omit)
   * @param     p_AddRequestResult  (default value: omit)
   * @param     p_NssrgInfo         (default value: omit)
   * @param     p_DisasterRoamingWaitRange (default value: omit)
   * @param     p_DisasterReturnWaitRange (default value: omit)
   * @param     p_DisasterPLMNList  (default value: omit)
   * @param     p_ForbidTAIList_Roaming (default value: omit)
   * @param     p_ForbidTAIList_RegProvService (default value: omit)
   * @param     p_ExtdCAGInfoList   (default value: omit)
   * @param     p_NsagInfo          (default value: omit)
   * @param     p_DisasterRoamingResult (default value: '0'B)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_RegistrationAcceptMsg(TypeOfRegistration_Type p_RegType,
                                          GMM_MobilityInfo_Type p_GMM_MobilityInfo,         // @sic R5-206426 sic@
                                          template (omit) NG_MobileIdentity p_GUTI,         // @sic R5s190719 sic@
                                          template (omit) NG_TrackingAreaIdList p_TAIList,
                                          template (omit) PLMN_List p_EPLMNs := omit,
                                          template (omit) NSSAI p_AllowedNSSAI := cs_NSSAI_Allowed_Def, // @sic R5s190109, R5-216256 sic@
                                          template (omit) RejectedNSSAI p_RejectedNSSAI := omit,
                                          template (omit) NSSAI p_ConfiguredNSSAI := omit,
                                          template (omit) NG_NetworkFeatureSupport p_NwkFeatureSupport := cs_NG_NetworkFeatureSupport_Def,
                                          template (omit) PDU_SessionStatus p_PDU_SessionStatus := omit,
                                          template (omit) PDU_SessionReactivationResult p_PDU_SessionReactResult := omit,
                                          template (omit) PDU_SessionReactivationError p_PDU_SessionReactError := omit,
                                          template (omit) LADN_Info p_LADN_Info := omit,
                                          template (omit) MICO_Ind p_MICO_Ind := omit,
                                          template (omit) NetworkSlicingInd p_NetworkSlicingInd := omit,
                                          template (omit) ServiceAreaIdList p_SAIList := omit,
                                          template (omit) GPRS_Timer3 p_T3512 := omit,
                                          template (omit) GPRS_Timer2 p_Non3GPPDereg := omit,
                                          template (omit) GPRS_Timer2 p_T3502 := omit,
                                          template (omit) EmergNumList p_EmergNumList := omit,
                                          template (omit) ExtdEmergNumList p_ExtdEmergNumList := omit,
                                          template (omit) SORTransparentContainer p_SOR := omit,
                                          template (omit) EAP_Message p_EAP := omit,
                                          template (omit) InclusionModeNSSAI p_InclusionModeNSSAI := omit,
                                          template (omit) OperatorAccessCatDefinitions p_AccessCatDefinition := omit,
                                          template (omit) NG_DRXparameter p_NG_DRXparameter := omit,
                                          template (omit) Non3GPP_NW_ProvidedPolicies p_Non3GPP_NW_ProvidedPolicies := omit,
                                          template (omit) EPS_BearerContextStatus p_EPS_BearerContextStatus := omit, // @sic R5s190543 sic@
                                          RegistrationAccessType p_Access := Access_3GPP,
                                          B1_Type p_SMSOverNAS := '0'B,
                                          B1_Type p_EmergencyRegistered := '0'B,          // @sic R5s201387 Baseline Moving sic@
                                          B1_Type p_NssaaPerformed := '0'B,               // @sic R5s201387 Baseline Moving sic@
                                          template (omit) ExtdDRXParams p_NegotiatedExtdDRXParams := omit, // @sic R5s201387 Baseline Moving sic@
                                          template (omit) GPRS_Timer3 p_T3447 := omit,    // @sic R5s201387 Baseline Moving sic@
                                          template (omit) GPRS_Timer3 p_T3448 := omit,
                                          template (omit) GPRS_Timer3 p_T3324 := omit,
                                          template (omit) UERadioCapId p_UERadioCapId := omit,
                                          template (omit) UERadioCapIdDeletion p_UERadioCapIdDeletion := omit,
                                          template (omit) NSSAI p_PendingNSSAI := omit,
                                          template (omit) NG_CipheringKeyData p_CipheringKeyData := omit,
                                          template (omit) CAGInfoList p_CAGInfoList := omit,
                                          template (omit) TruncatedS_TMSIConfig p_TruncatedS_TMSIConfig := omit,
                                          template (omit) WUSAssistInfo p_WUSAssistInfo := omit,
                                          template (omit) NB_N1ModeDRXParams p_NB_N1ModeDRXParams := omit,
                                          template (omit) ExtdRejectedNSSAI p_ExtdRejectedNSSAI := omit,
                                          template (omit) ServiceLvlAAContainer p_ServiceLvlAA := omit,
                                          template (omit) PEIPS_AssistInfo p_NegotiatedPEIPS_AssistInfo := omit,
                                          template (omit) NG_AddReqResult p_AddRequestResult := omit,
                                          template (omit) NSSRG_Info p_NssrgInfo := omit,
                                          template (omit) RegistrationWaitRange p_DisasterRoamingWaitRange := omit,
                                          template (omit) RegistrationWaitRange p_DisasterReturnWaitRange := omit,
                                          template (omit) DisasterPLMNList p_DisasterPLMNList := omit,
                                          template (omit) NG_TrackingAreaIdList p_ForbidTAIList_Roaming := omit,
                                          template (omit) NG_TrackingAreaIdList p_ForbidTAIList_RegProvService := omit,
                                          template (omit) ExtdCAGInfoList p_ExtdCAGInfoList := omit,
                                          template (omit) NSAG_Info p_NsagInfo := omit,
                                          B1_Type p_DisasterRoamingResult := '0'B) return template (value) NG_NAS_DL_Message_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_NASMsg;
    var B3_Type v_Access;
    var template (omit) NG_NetworkFeatureSupport v_NwkFeatureSupport := p_NwkFeatureSupport;
    var template (omit) GPRS_Timer3 v_T3512 := omit;
    var template (omit) PDU_SessionStatus v_PDU_SessionStatus;
    var template (omit) EPS_BearerContextStatus v_EPS_BearerContextStatus;
    var template (omit) UERadioCapId v_UERadioCapId := omit;
    
    select (p_Access) {
      case (Access_3GPP) {
        v_Access := tsc_NG_RegResult_3GPP;
      }
      case (Non3GPP) {
        v_Access := tsc_NG_RegResult_Non3GPP;
      }
      case (Both_3GPP_Non3GPP) {
        v_Access := tsc_NG_RegResult_Both;
      }
      case else {
      FatalError(__FILE__, __LINE__, "invalid access type");
      }
    }
    if (isvalue(p_T3512)) {
      v_T3512 := p_T3512;
    } else {
      select (p_RegType) {
        case (Mobility, Periodic) { // Do nothing
        }
        case (Emergency) { // @sic R5-196637 R5-198540 sic@
        }
        case (Initial_NoSecurity, Initial_Secure) {
          v_T3512 := cs_GPRS_Timer2_3_IEI ('5E'O, '111'B, '00000'B);
        }
      }
    }
    if (isvalue(p_PDU_SessionStatus)) { // @sic R5-206426 sic@
      v_PDU_SessionStatus := p_PDU_SessionStatus;
    } else {
      v_PDU_SessionStatus := p_GMM_MobilityInfo.SessionStatus;
    }
    if (isvalue(p_EPS_BearerContextStatus)) { // @sic R5-206426 sic@
      v_EPS_BearerContextStatus := p_EPS_BearerContextStatus;
    } else {
      v_EPS_BearerContextStatus := p_GMM_MobilityInfo.EPSBearerStatus;
    }

    if (isvalue(p_UERadioCapId)) { // @sic R5-206419 sic@
      v_UERadioCapId := p_UERadioCapId;
    } else if (pc_5GC_RACS) {
      v_UERadioCapId := p_GMM_MobilityInfo.UERadioCapId;
    }

    // if (p_GSM_MobilityInfo.PDUType == SST_URLLC or SST_V2X ) v_NwkFeatureSupport := omit FFS
    v_NASMsg := cs_NG_REGISTRATION_ACCEPT(cs_RegistrationResult (v_Access, p_SMSOverNAS, p_EmergencyRegistered, p_NssaaPerformed, p_DisasterRoamingResult),   // @sic R5s221179 Baseline Moving sic@
                                          p_GUTI,
                                          p_EPLMNs,
                                          p_TAIList,
                                          p_AllowedNSSAI,
                                          p_RejectedNSSAI,
                                          p_ConfiguredNSSAI,
                                          v_NwkFeatureSupport,
                                          v_PDU_SessionStatus,
                                          p_PDU_SessionReactResult,
                                          p_PDU_SessionReactError,
                                          p_LADN_Info,
                                          p_MICO_Ind,
                                          p_NetworkSlicingInd,
                                          p_SAIList,
                                          v_T3512,
                                          p_Non3GPPDereg,
                                          p_T3502,
                                          p_EmergNumList,
                                          p_ExtdEmergNumList,
                                          p_SOR,
                                          p_EAP,
                                          p_InclusionModeNSSAI,
                                          p_AccessCatDefinition,
                                          p_NG_DRXparameter,
                                          p_Non3GPP_NW_ProvidedPolicies,
                                          v_EPS_BearerContextStatus,
                                          p_NegotiatedExtdDRXParams,  // @sic R5s201387 Baseline Moving sic@
                                          p_T3447,
                                          p_T3448,
                                          p_T3324,
                                          v_UERadioCapId,
                                          p_UERadioCapIdDeletion,
                                          p_PendingNSSAI,
                                          p_CipheringKeyData,
                                          p_CAGInfoList,
                                          p_TruncatedS_TMSIConfig,
                                          p_WUSAssistInfo,
                                          p_NB_N1ModeDRXParams,
                                          p_ExtdRejectedNSSAI,    // @sic R5s221179 Baseline Moving sic@
                                          p_ServiceLvlAA,
                                          p_NegotiatedPEIPS_AssistInfo,
                                          p_AddRequestResult,
                                          p_NssrgInfo,
                                          p_DisasterRoamingWaitRange,
                                          p_DisasterReturnWaitRange,
                                          p_DisasterPLMNList,
                                          p_ForbidTAIList_Roaming,
                                          p_ForbidTAIList_RegProvService,
                                          p_ExtdCAGInfoList,
                                          p_NsagInfo);
    return v_NASMsg;
  }

  /*
   * @desc      build the SECURITY MODE COMMAND
   * @param     p_SecurityParams
   * @param     p_RegType
   * @param     p_GMM_MobilityInfo
   * @param     p_IMEISVReq         (default value: false)
   * @param     p_AddInfo           (default value: omit)
   * @param     p_EAP               (default value: omit)
   * @param     p_ABBA              (default value: omit)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_SecurityModeCmdMsg(NG_NAS_SecurityParams_Type p_SecurityParams,
                                       TypeOfRegistration_Type p_RegType,
                                       GMM_MobilityInfo_Type p_GMM_MobilityInfo,
                                       boolean p_IMEISVReq := false,
                                       template (omit) AdditionalSecurityInfo p_AddInfo := omit,
                                       template (omit) EAP_Message p_EAP := omit,
                                       template (omit) ABBA p_ABBA := omit) return template (value) NG_NAS_DL_Message_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_NASMsg;
    var template (omit)  AdditionalSecurityInfo v_AddInfo := p_AddInfo;
    var template (omit) IMEISV_Request v_IMEISV_Request := omit;
    var template (omit) NAS_SecurityAlgorithms v_EPSAlgs := omit;
    var NG_UE_SecurityCapability v_NG_UE_SecurityCapability;
    var template (omit) S1_UE_SecurityCapability v_ReplayedCap := omit;
    
    if (isvalue(p_GMM_MobilityInfo.UECap)) { // @sic R5s190109 sic@
      v_NG_UE_SecurityCapability := p_GMM_MobilityInfo.UECap;
      v_NG_UE_SecurityCapability.iei := omit;
    } else {
      FatalError(__FILE__, __LINE__, "UE Capabilities not included in Registration Request");
    }
    
    if (isvalue(p_GMM_MobilityInfo.GMMCap)) {
      if (match('1'B, p_GMM_MobilityInfo.GMMCap.s1Cap)) {
        v_EPSAlgs := cs_NAS_SecurityAlgorithms(px_NAS_CipheringAlgorithm, px_NAS_IntegrityProtAlgorithm, '57'O); // @sic R5s190285 sic@
        if (isvalue(p_GMM_MobilityInfo.S1NwkCap)) {
          v_ReplayedCap.ieValue := f_EPS_FillNAS_SecurityCapability_Common(p_GMM_MobilityInfo.S1NwkCap, omit);  // @sic R5s190421 sic@
          v_ReplayedCap.iei := '19'O; // @sic R5s190421 sic@
        }
      }
    }

    if (p_IMEISVReq) {
      v_IMEISV_Request := cds_NG_IMEISV_Request;
    }

    if (p_RegType == Initial_NoSecurity) {
    // Must ensure UE sends complete initial message if SS doesn't have security
      if (isvalue(v_AddInfo)) {
        v_AddInfo.rinmr := '1'B;
      } else {
        v_AddInfo := cs_AdditionalSecurityInfo('1'B);
      }
    }
    v_NASMsg := cs_NG_SECURITY_MODE_COMMAND(cs_NG_NAS_SecurityAlgorithms (p_SecurityParams.NAS_Ciphering.Algorithm, p_SecurityParams.NAS_Integrity.Algorithm),
                                            p_SecurityParams.KSIamf,
                                            v_NG_UE_SecurityCapability,
                                            v_IMEISV_Request,
                                            v_EPSAlgs,
                                            v_AddInfo,
                                            p_EAP,
                                            p_ABBA,
                                            v_ReplayedCap);
    return v_NASMsg;
  }

  /*
   * @desc      Check the SECURITY MODE COMPLETE
   * @param     p_NASMsgs
   * @param     p_RegType
   * @param     p_IMEISVReq         (default value: false)
   * @param     p_NonIMEISV_PEI     (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_SecurityModeCompleteMsg(NG_NAS_UL_Pdu_Type p_NASMsgs,
                                              TypeOfRegistration_Type p_RegType,
                                              boolean p_IMEISVReq := false,
                                              template NG_MobileIdentity p_NonIMEISV_PEI := *) return boolean
  {
    var template NG_MobileIdentity v_IMEISV := omit;
    var template ReplayedNASMessageContainer v_ExpectedMsg := omit;

    if (p_IMEISVReq) { // if IMEISV is requested
      v_IMEISV := f_NG_Imeisv2MobileIdentity (px_IMEISV_Def);
      v_IMEISV.iei := '77'O;
    }
    if (p_RegType == Initial_NoSecurity) {
      // don't check the contents here as it's encoded, but it should be present
      v_ExpectedMsg := ?;
    }
    return match(p_NASMsgs.Msg, cr_NG_SECURITY_MODE_COMPLETE (v_IMEISV, v_ExpectedMsg, p_NonIMEISV_PEI)); // @sic R5s201387 Baseline Moving sic@
  }

  /*
   * @desc      Check the SERVICE REQUEST message
   * @param     p_ReceivedMsgs
   * @param     p_KSI
   * @param     p_S_TMSI
   * @param     p_ServiceType       (default value: '0010'B)
   * @param     p_ConnectionType    (default value: STATE_IDLE_1A)
   * @param     p_ULDataStatus      (default value: *)
   * @param     p_PDU_SessionStatus (default value: *)
   * @param     p_AllowedPDU_SessionStatus (default value: *)
   * @param     p_UeRequestType (default value: *)
   * @param     p_PagingRestrict (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_ServiceReqMsg(NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                    template (present) NAS_KeySetIdentifier p_KSI,
                                    template (present) NG_MobileIdentity p_S_TMSI,
                                    template (present) B4_Type p_ServiceType := '0010'B, // @sic R5s190109 sic@
                                    NG_STATE_Type p_ConnectionType := STATE_IDLE_1A,
                                    template ULDataStatus p_ULDataStatus := *,
                                    template PDU_SessionStatus p_PDU_SessionStatus := *,
                                    template AllowedPDU_SessionStatus p_AllowedPDU_SessionStatus := *,
                                    template UE_RequestType p_UeRequestType := *,
                                    template NG_PagingRestriction p_PagingRestrict := *) return boolean
  {
    var NG_NAS_UL_Message_Type v_NASMsg;
    
    v_NASMsg := p_ReceivedMsgs.Msg;
    
    if (p_ConnectionType == STATE_IDLE_1A) {
      // If this is an initial NAS message check the 'first' message to make sure it only includes cleartext IEs
      if (not match (v_NASMsg, cr_NG_SERVICE_REQUEST (p_ServiceType,
                                                    p_KSI,
                                                    p_S_TMSI,
                                                    omit,
                                                    omit,
                                                    omit,
                                                    *,
                                                    omit,
                                                    omit))) {
        FatalError(__FILE__, __LINE__, "Initial Service Req included non-cleartext IEs");
      }
      if (isvalue(p_ReceivedMsgs.PiggybackedPduList)) {
      /* this will be the un-ciphered message from the NAS Container
         if the SS couldn't decipher the message (because it doesn't have the security context, e.g. at the start of a test)
         this field will be set to omit
      */
        v_NASMsg := valueof(p_ReceivedMsgs.PiggybackedPduList[0].Msg);
      }
    }
    // Now check the full message, if present, against all expected values
    return match(v_NASMsg, cr_NG_SERVICE_REQUEST (p_ServiceType,
                                                  p_KSI,
                                                  p_S_TMSI,
                                                  p_ULDataStatus,
                                                  p_PDU_SessionStatus,
                                                  p_AllowedPDU_SessionStatus,
                                                  *,
                                                  p_UeRequestType,    // @sic R5s221179 Baseline Moving sic@
                                                  p_PagingRestrict));
  }

  /*
   * @desc      Check the CONTROL PLANE SERVICE REQUEST message
   * @param     p_ReceivedMsgs
   * @param     p_KSI
   * @param     p_CP_ServiceType
   * @param     p_CIoTSmallDataContainer  (default value: false) If this is expected, the value must be checked outside this function
   * @param     p_PayloadContainerType      (default value: *)
   * @param     p_PayloadContainer      (default value: *)
   * @param     p_NG_PDU_SessionId      (default value: *)
   * @param     p_PDU_SessionStatus      (default value: *)
   * @param     p_ReleaseAssistanceInd      (default value: *)
   * @param     p_ULDataStatus      (default value: *)
   * @param     p_AdditionalInfo      (default value: *)
   * @param     p_ConnectionType    (default value: STATE_IDLE_1A)
   * @param     p_UeRequestType      (default value: *)
   * @param     p_PagingRestrict      (default value: *)
   * @return    boolean
   */
  function f_Check_NG_ControlPlaneServiceReqMsg(NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                                template (present) NAS_KeySetIdentifier p_KSI,
                                                template (present) CP_ServiceType p_CP_ServiceType,
                                                boolean p_CIoTSmallDataContainer := false,
                                                template PayloadContainerType p_PayloadContainerType := *,
                                                template PayloadContainer p_PayloadContainer := *,
                                                template NG_PDU_SessionId p_NG_PDU_SessionId := *,
                                                template PDU_SessionStatus p_PDU_SessionStatus := *,
                                                template ReleaseAssistanceInd p_ReleaseAssistanceInd := *,
                                                template ULDataStatus p_ULDataStatus := omit,
                                                template AdditionalInformation p_AdditionalInfo := *,
                                                template AllowedPDU_SessionStatus p_AllowedPDU_SessionStatus,
                                                template UE_RequestType p_UeRequestType := *,
                                                template NG_PagingRestriction p_PagingRestrict := *,
                                                NG_STATE_Type p_ConnectionType := STATE_IDLE_1A) return boolean
  {
    var NG_NAS_UL_Message_Type v_NASMsg;
    var template CIoTSmallDataRxdString v_SmallData := omit;
    
    if (p_CIoTSmallDataContainer) {
      v_SmallData := ?;
    }
    v_NASMsg := p_ReceivedMsgs.Msg;
    
    if (p_ConnectionType == STATE_IDLE_1A) {
      // If this is an initial NAS message check the 'first' message to make sure it only includes cleartext IEs
      if (not match (v_NASMsg, cr_NG_CP_SERVICE_REQUEST (p_KSI,
                                                    p_CP_ServiceType,
                                                    v_SmallData,      // The small data container may be present, but still ciphered
                                                    omit,
                                                    omit,
                                                    omit,
                                                    omit,
                                                    omit,
                                                    omit,
                                                    omit,
                                                    omit,
                                                    *,
                                                    omit,
                                                    omit))) {
        FatalError(__FILE__, __LINE__, "Initial Service Req included non-cleartext IEs");
      }
      if (isvalue(p_ReceivedMsgs.PiggybackedPduList)) {
      /* this will be the un-ciphered message
         if the SS couldn't decipher the message (because it doesn't have the security context, e.g. at the start of a test)
         this field will be set to omit
         
         This will either be cleartext IEs + unciphered small data container,
         or cleartext + noncleartext IEs (but not small data container)
      */
        v_NASMsg := valueof(p_ReceivedMsgs.PiggybackedPduList[0].Msg);
      }
    }
    // Now check the full message, if present, against all expected values
    return match(v_NASMsg, cr_NG_CP_SERVICE_REQUEST (p_KSI,
                                                     p_CP_ServiceType,
                                                     v_SmallData,
                                                     p_PayloadContainerType,
                                                     p_PayloadContainer,
                                                     p_NG_PDU_SessionId,
                                                     p_PDU_SessionStatus,
                                                     p_ReleaseAssistanceInd,
                                                     p_ULDataStatus,
                                                     p_AdditionalInfo,
                                                     p_AllowedPDU_SessionStatus,
                                                     *,
                                                     p_UeRequestType,    // @sic R5s221179 Baseline Moving sic@
                                                     p_PagingRestrict));
  }

  /*
   * @desc      Check the CIoT Small Data Container in the CONTROL PLANE SERVICE REQUEST message
   * @param     p_ReceivedIE
   * @param     p_IEL
   * @param     p_DataType
   * @param     p_DDX
   * @param     p_PduSessionId
   * @param     p_DataContents
   * @param     p_LengthOfAddInfo      (default value: omit)
   * @param     p_AddInfo      (default value: omit)
   * @return    boolean
   */
  function f_Check_CIoTSmallDataContainer(CIoTSmallDataRxdString p_ReceivedIE,
                                          template (present) B3_Type p_DataType,
                                          template (present) B2_Type p_DDX,                 /* set to 00 for dataType = 001 */
                                          template (present) B3_Type p_PduSessionId,        /* set to 00 for dataType = 010 or 001 */
                                          octetstring p_DataContents,
                                          template Type4Length_Type p_LengthOfAddInfo := omit,
                                          template octetstring p_AddInfo := omit) return boolean
  {
    var  template (omit) CIoTSmallDataContainer v_SmallData := fl_Decode_CIoTSmallDataContainer (p_ReceivedIE);
    
    if (not (isvalue(v_SmallData))){
      return false;
    } else {
      return match (valueof(v_SmallData), cr_CIoTSmallDataContainer (p_DataType,
                                                            p_DDX,
                                                            p_PduSessionId,
                                                            p_LengthOfAddInfo,
                                                            p_AddInfo,
                                                            p_DataContents));
    }
  }
  
  /*
   * @desc      Decode the CIoT Small Data Container in the CONTROL PLANE SERVICE REQUEST message
   * @param     p_ReceivedIE
   * @return    template (omit) CIoTSmallDataContainer
   */
  function fl_Decode_CIoTSmallDataContainer(CIoTSmallDataRxdString p_ReceivedIE) return template (omit) CIoTSmallDataContainer
  {
    var template (omit) CIoTSmallDataContainer v_ReturnOmit := omit;
    var CIoTSmallDataContainer v_SmallData;
    var octetstring v_OctetString := p_ReceivedIE.encodedstring;
    var bitstring v_Bitstring := oct2bit(v_OctetString);
    
    if (decvalue(v_Bitstring, v_SmallData) != 0) {
      return v_ReturnOmit;
    } else if (p_ReceivedIE.iei != '6F'O) {  // check iei separately
      return v_ReturnOmit;
    } else {
      return v_SmallData;
    }
  }
  
  /*
   * @desc      Get the SERVICE ACCEPT message
   * @param     p_PDU_SessionStatus (default value: omit)
   * @param     p_PDU_SessionReactivationResult (default value: omit)
   * @param     p_PDU_SessionReactivationError (default value: omit)
   * @param     p_EAP               (default value: omit)
   * @param     p_T3448             (default value: omit)
   * @param     p_AddRequestResult             (default value: omit)
   * @param     p_ForbidTAIList_Roaming             (default value: omit)
   * @param     p_ForbidTAIList_RegProvService             (default value: omit)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_ServiceAcceptMsg(template (omit) PDU_SessionStatus p_PDU_SessionStatus := omit,
                                     template (omit) PDU_SessionReactivationResult p_PDU_SessionReactivationResult := omit,
                                     template (omit) PDU_SessionReactivationError p_PDU_SessionReactivationError := omit,
                                     template (omit) EAP_Message p_EAP := omit,
                                     template (omit) GPRS_Timer2 p_T3448 := omit,
                                     template (omit) NG_AddReqResult p_AddRequestResult := omit,
                                     template (omit) NG_TrackingAreaIdList p_ForbidTAIList_Roaming := omit,
                                     template (omit) NG_TrackingAreaIdList p_ForbidTAIList_RegProvService := omit) return template (value) NG_NAS_DL_Message_Type
  {
    return cs_NG_SERVICE_ACCEPT (p_PDU_SessionStatus,
                                 p_PDU_SessionReactivationResult,
                                 p_PDU_SessionReactivationError,
                                 p_EAP,
                                 p_T3448,  // @sic R5s201387 Baseline Moving sic@
                                 p_AddRequestResult,  // @sic R5s221179 Baseline Moving sic@
                                 p_ForbidTAIList_Roaming,
                                 p_ForbidTAIList_RegProvService);
  }

  /*
   * @desc      Check the DEREGISTRATION REQUEST MO message
   * @param     p_NASMsg
   * @param     p_DeregisterType
   * @param     p_MobileId          (default value: ?)
   * @param     p_KSI               (default value: ?)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_DeregistrationReqMOMsg(NG_NAS_UL_Message_Type p_NASMsg,
                                           template (present) DeregisterType p_DeregisterType,
                                           template (present) NG_MobileIdentity p_MobileId := ?,
                                           template (present) NAS_KeySetIdentifier p_KSI := ?) return boolean
  {
    return match (p_NASMsg, cr_NG_DEREGISTRATION_REQUEST_MO (p_DeregisterType, p_KSI, p_MobileId));
  }

  /*
   * @desc      Get the DEREGISTRATION REQUEST MT message
   * @param     p_DeregisterType
   * @param     p_Cause
   * @param     p_T3346             (default value: omit)
   * @param     p_RejectedNSSAI             (default value: omit)
   * @param     p_CAGInfoList             (default value: omit)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_DeregistrationReqMTMsg(template (value) DeregisterType p_DeregisterType,
                                           template (omit) GMM_GSM_Cause p_Cause,
                                           template (omit) GPRS_Timer2 p_T3346 := omit,
                                           template (omit) RejectedNSSAI p_RejectedNSSAI := omit,  // @sic R5s201387 Baseline Moving sic@
                                           template (omit) CAGInfoList p_CAGInfoList := omit) return template (value) NG_NAS_DL_Message_Type
  {
    return cs_NG_DEREGISTRATION_REQUEST_MT (p_DeregisterType, p_Cause, p_T3346, p_RejectedNSSAI, p_CAGInfoList);  // @sic R5s201387 Baseline Moving sic@
  }

  /*
   * @desc      build the AUTHENTICATION REQUEST for 5G AKA
   * @param     p_SecurityParams    (by reference)
   * @param     p_PLMN
   * @param     p_AuthenticationError (default value: noError)
   * @param     p_NID  (default value: omit)
   * @param     p_Identity  (default value:  := px_IMSI_Def)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_5GAKA_AuthenticationReqMsg(inout NG_NAS_SecurityParams_Type p_SecurityParams,
                                            NAS_PlmnId p_PLMN,
                                            AuthenticationError_Type p_AuthenticationError := noError,
                                            template (omit) hexstring p_NID := omit,
                                            hexstring p_Identity := px_IMSI_Def) return template (value) NG_NAS_DL_Message_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_NASMsg;
    
    // Evaluate Authentication parameters and generate new keys
    p_SecurityParams := f_NG_NAS_AuthenticationInit(p_SecurityParams, p_PLMN, p_Identity, p_AuthenticationError, -, p_NID); // @sic R5-197217, R5s220753, R5s230215 sic@
    v_NASMsg := cs_NG_AUTHENTICATION_REQUEST (p_SecurityParams.KSIamf,
                                              cs_ABBA (p_SecurityParams.ABBA, omit), // @sic R5s190109 sic@
                                              cs_GMM_AuthRAND(p_SecurityParams.AuthParams.RandValue),
                                              cs_GSM_AUTN(p_SecurityParams.AuthParams.AUTN));
    return v_NASMsg;
  }

  /*
   * @desc      build the AUTHENTICATION REQUEST for EAP AKA
   * @param     p_SecurityParams    (by reference)
   * @param     p_PLMN
   * @param     p_NID  (default value: omit)
   * @param     p_Identity  (default value:  := px_IMSI_Def)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_EAP_AuthenticationReqMsg(inout NG_NAS_SecurityParams_Type p_SecurityParams,
                                          NAS_PlmnId p_PLMN,
                                          template (omit) hexstring p_NID := omit,
                                          hexstring p_Identity := px_IMSI_Def) return template (value) NG_NAS_DL_Message_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_NASMsg;
    var template (value) EAP_Message v_EAP;

    // Evaluate Authentication parameters and generate new keys
    p_SecurityParams := f_NG_EAP_AuthenticationInit(p_SecurityParams, p_PLMN, hex2str(p_Identity), -, -, p_NID); // @sic R5s220753, R5s230215 sic@
    v_EAP := cs_EAP_Message (f_NG_EAP_ChallengeReq (p_SecurityParams, p_PLMN, -, p_NID));  // @sic R5s230229 sic@
    v_NASMsg := cs_NG_AUTHENTICATION_REQUEST (p_SecurityParams.KSIamf,
                                              cs_ABBA (p_SecurityParams.ABBA, omit), // @sic R5s190109 sic@
                                              -,
                                              -,
                                              v_EAP);
    return v_NASMsg;
  }
  //----------------------------------------------------------------------------
  /*
   * @desc      Check if received message is either an Authentication Response or an Authenticationfailure
   * @param     p_SecurityParams    (by reference)
   * @param     p_ReceivedMsg
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_5GAKA_AuthenticationResponseFailure(inout NG_NAS_SecurityParams_Type p_SecurityParams,
                                                       NG_NAS_UL_Message_Type p_ReceivedMsg) return boolean
  {
    var boolean v_Result := false;
    var B32_128_Type v_ReceivedRES;
    
    if (match (p_ReceivedMsg, cr_NG_AUTHENTICATION_RESPONSE)) {
      v_ReceivedRES := p_ReceivedMsg.authentication_Response.authResponseParam.res;
      if (v_ReceivedRES == substr(p_SecurityParams.AuthParams.XRES, 0, lengthof(v_ReceivedRES))) {
        v_Result := true;
      } else {
        v_Result := false;
      }
      p_SecurityParams.AuthParams.XRESLength := px_NAS_5GC_XRES_Length; // @sic R5w190117 sic@
    } else if (match (p_ReceivedMsg, cr_NG_AUTHENTICATION_FAILURE)) {
      v_Result := false;
    }
    return v_Result;
  }

  /*
   * @desc      Check received Authentication Response message
   * @param     p_SecurityParams    (by reference)
   * @param     p_ReceivedMsg
   * @param     p_ResultInd         (default value: *)
   * @param     p_Id                (default value: '00'O)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_EAPAKA_AuthenticationResponse (inout NG_NAS_SecurityParams_Type p_SecurityParams,
                                                  NG_NAS_UL_Message_Type p_ReceivedMsg,
                                                  template EAP_AT_RESULT_IND p_ResultInd := *,
                                                  O1_Type p_Id := '00'O) return boolean
  {
    if (not match (p_ReceivedMsg, cr_NG_AUTHENTICATION_RESPONSE (omit, cr_EAP_Message()))) { // @sic R5-201142 sic@
      return false;
    }
     return f_NG_EAP_SuccessfulAuthenticationResponse(p_SecurityParams, p_ReceivedMsg.authentication_Response.eapMessage.eapMsg, p_ResultInd, p_Id); // @sic R5-201142, R5s201483 sic@
  }

  /*
   * @desc      build the AUTHENTICATION RESULT
   * @param     p_SecurityParams
   * @param     p_EAP_Msg       (default: cs_EAP_Success)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (NR5GC)
   */
  function f_Get_NG_AuthenticationResultMsg(NG_NAS_SecurityParams_Type p_SecurityParams,
                                            template (value) EAP_Message_Type p_EAP_Msg := cs_EAP_Success) return template (value) NG_NAS_DL_Message_Type
  {
    return cs_NG_AUTHENTICATION_RESULT(p_SecurityParams.KSIamf,
                                       cs_EAP_Message(bit2oct(encvalue(p_EAP_Msg)), omit), // @sic R5s201223, R5-205579 sic@
                                       cs_ABBA (p_SecurityParams.ABBA));
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      Check the PDU SESSION ESTABLISHMENT REQUEST, Piggybacked into the UL NAS Transport
   * @param     p_GSM_MobilityInfo  (by reference)
   * @param     p_ReceivedMsgs
   * @param     p_PDU_SessionId     (default value: ?)
   * @param     p_PTI               (default value: omit)
   * @param     p_IntegrityProtMaxDataRate (default value: ?)
   * @param     p_PDU_SessionType   (default value: omit)
   * @param     p_SSC_Mode          (default value: *)
   * @param     p_UECap             (default value: *)
   * @param     p_MaxNumPacketFilters (default value: *)
   * @param     p_AlwaysOnPDUSessionReq (default value: *)
   * @param     p_PDUReq            (default value: *)
   * @param     p_ExtdPCO           (default value: *)
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: cr_NG_Request_Type('001'B))
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @param     p_IPHeaderCompConfig (default value: *)
   * @param     p_DS_TT_EthernetPortMACAddr (default value: *)
   * @param     p_UE_DS_TT_ResidenceTime (default value: *)
   * @param     p_PortManagementInfoContainer (default value: *)
   * @param     p_EthernetHeaderCompConfig (default value: *)
   * @param     p_SuggestedInterfaceId (default value: *)
   * @param     p_ServiceLvlAA (default value: *)
   * @param     p_RequestedMBS (default value: *)
   * @param     p_PduSessionPairId (default value: *)
   * @param     p_RSN (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_PDUSessionEstablishmentReq(out GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                                 NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                                 template (present) O1_Type p_PDU_SessionId := ?,
                                                 template ProcedureTransactionIdentifier p_PTI := omit,
                                                 template IntegrityProtMaxDataRate p_IntegrityProtMaxDataRate := ?,
                                                 template PDU_SessionType p_PDU_SessionType := omit,
                                                 template SSC_Mode p_SSC_Mode := *, // @sic R5s200162 sic@
                                                 template NG_UE_SM_Cap p_UECap := *, // @sic R5s200162 sic@
                                                 template MaxNumPacketFilters p_MaxNumPacketFilters := *, // @sic R5s200162 sic@
                                                 template AlwaysOnPDUSessionReq p_AlwaysOnPDUSessionReq := *, // @sic R5s200106 sic@
                                                 template SM_PDU_DN_RequestContainer p_PDUReq := *, // @sic R5s200162 sic@
                                                 template ExtdProtocolConfigOptions p_ExtdPCO := *, // @sic R5s200162 sic@
                                                 template NG_PDU_SessionId p_OldPDU_SessionId  := *,
                                                 template NG_Request_Type p_RequestType  := cr_NG_Request_Type('001'B),
                                                 template S_NSSAI_Type p_S_NSSAI  := *,
                                                 template DNN p_DNN  := *,
                                                 template AdditionalInformation p_AdditionalInfo  := *,
                                                 template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                                 template ReleaseAssistanceInd p_ReleaseAssistanceInd := *,
                                                 template IPHeaderCompressionConfig p_IPHeaderCompConfig := *,
                                                 template DS_TT_EthernetPortMACAddr p_DS_TT_EthernetPortMACAddr := *,
                                                 template UE_DS_TT_ResidenceTime p_UE_DS_TT_ResidenceTime := *,
                                                 template PortManagementInfoContainer p_PortManagementInfoContainer := *,
                                                 template EthernetHeaderCompressConfig p_EthernetHeaderCompConfig := *,
                                                 template PDU_Address p_SuggestedInterfaceId := *,
                                                 template ServiceLvlAAContainer p_ServiceLvlAA := *,
                                                 template RequestedMBSContainer p_RequestedMBS := *,
                                                 template PDUSessionPairId p_PduSessionPairId := *,
                                                 template RSN p_RSN := *) return boolean
  {
    var boolean v_Result := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    var template (present) ProcedureTransactionIdentifier v_PTI;
    var template (present) PDU_SessionType v_SessionType;
    
    if (ispresent(p_PTI)) {
      v_PTI := p_PTI;
    } else {
      v_PTI := complement('00'O, 'FF'O);
    }
    if (ispresent(p_PDU_SessionType)) {
      v_SessionType := p_PDU_SessionType;
    } else {
      v_SessionType := cr_PDU_SessionType(('001'B, '010'B, '011'B, '101'B)); // @sic R5s190704, R5-221493 sic@
    }
    // Check NAS Transport msg first
    v_Result := f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_PDU_SessionId,
                                           p_OldPDU_SessionId,
                                           p_RequestType,
                                           p_S_NSSAI,
                                           p_DNN,
                                           p_AdditionalInfo,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd);
    if (not v_Result) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_PDU_SESSION_ESTABLISHMENT_REQUEST (cr_NG_PDU_SessionId(omit, p_ReceivedMsgs.Msg.ul_Nas_Transport.pduSessionId.sessionId), // @sic R5-191222 sic@
                                                                         v_PTI,
                                                                         v_SessionType,
                                                                         p_SSC_Mode,
                                                                         p_UECap,
                                                                         p_MaxNumPacketFilters,
                                                                         p_IntegrityProtMaxDataRate,
                                                                         p_AlwaysOnPDUSessionReq,
                                                                         p_PDUReq,
                                                                         p_ExtdPCO,
                                                                         p_IPHeaderCompConfig,    // @sic R5s201387 Baseline Moving sic@
                                                                         p_DS_TT_EthernetPortMACAddr,
                                                                         p_UE_DS_TT_ResidenceTime,
                                                                         p_PortManagementInfoContainer,
                                                                         p_EthernetHeaderCompConfig,
                                                                         p_SuggestedInterfaceId,
                                                                         p_ServiceLvlAA,      // @sic R5s221179 Baseline Moving sic@
                                                                         p_RequestedMBS,
                                                                         p_PduSessionPairId,
                                                                         p_RSN))) {
      v_Result := true;
    } else {  // @sic R5s190944 sic@
      v_Result := false;
    }
    p_GSM_MobilityInfo.SessionId := v_GSMMsg.pdu_Session_Establishment_Request.pduSessionId.sessionId; // @sic R5s00564 sic@
    p_GSM_MobilityInfo.PTI := v_GSMMsg.pdu_Session_Establishment_Request.procedureTransactionIdentifier;
    p_GSM_MobilityInfo.SessionType := v_GSMMsg.pdu_Session_Establishment_Request.pduSessionType.typeValue;
    p_GSM_MobilityInfo.EPS_Bearer := omit; // these will be set in the Accept message @sic R5-204400 sic@
    p_GSM_MobilityInfo.PdnIndex := omit;   // these will be set in the Accept message @sic R5-204400 sic@
    
    if (ispresent (p_ReceivedMsgs.Msg.ul_Nas_Transport.dnn)) {
      p_GSM_MobilityInfo.DNN := p_ReceivedMsgs.Msg.ul_Nas_Transport.dnn;
    } else {
      p_GSM_MobilityInfo.DNN := omit;
    }
    p_GSM_MobilityInfo.PDUType := f_GetPDNTypeFromDNN(p_GSM_MobilityInfo.DNN);  // @sic R5-206296 sic@

    if (isvalue(p_PDU_SessionType)) { // @sic R5-227473 sic@
      if (match ('101'B, p_PDU_SessionType.typeValue)) {
        // make sure the correct PDU Type is set as this is used to decide other IE values
        p_GSM_MobilityInfo.PDUType := Ethernet_DNN;
      }
    }
    
    if (ispresent (v_GSMMsg.pdu_Session_Establishment_Request.alwaysOnPDUSessionReq)) {
      p_GSM_MobilityInfo.AlwaysOn := v_GSMMsg.pdu_Session_Establishment_Request.alwaysOnPDUSessionReq;
    } else {
      p_GSM_MobilityInfo.AlwaysOn := omit;
    }
    if (match(p_GSM_MobilityInfo.PDUType, (URLLC_DNN, Ethernet_DNN))) { // @sic R5s221179, R5-227473 sic@
      if (not match(p_GSM_MobilityInfo.AlwaysOn, cr_AlwaysOnRequested)) {
        v_Result := false;
      }
    }

    if (ispresent (v_GSMMsg.pdu_Session_Establishment_Request.extdProtocolConfigurationOptions)) {
      p_GSM_MobilityInfo.PCO := v_GSMMsg.pdu_Session_Establishment_Request.extdProtocolConfigurationOptions;
    } else {
      p_GSM_MobilityInfo.PCO := omit;
    }
    if (pc_PS_data_off) { // @sic R5-216155 sic@
      v_Result := f_ExtdProtocolConfigOptions_CheckPSDataOff(p_GSM_MobilityInfo.PCO);
    }
    if (ispresent (p_ReceivedMsgs.Msg.ul_Nas_Transport.s_NSSAI)) { // @sic R5s210148 sic@
      p_GSM_MobilityInfo.NSSAI := p_ReceivedMsgs.Msg.ul_Nas_Transport.s_NSSAI;
    } else {
      p_GSM_MobilityInfo.NSSAI := omit;
    }
    return v_Result;
  }

  /*
   * @desc      function to get/initialise p_DNN
   * @param     p_PLMN
   * @param     p_PDUType
   * @param     p_DNN
   * @return    template (value) DNN
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_NG_GetDNN(NAS_PlmnId p_PLMN,
                       PDU_PDN_DNN_Type p_PDUType,
                       template (omit) DNN p_DNN) return template (value) DNN
  { // @sic R5-221467 sic@
    var octetstring v_DNNValue;
    
    if (isvalue (p_DNN)) {  // @sic R5s210130 sic@
      v_DNNValue := valueof(p_DNN.dnnValue);
    } else if (p_PDUType == IMS_DNN) {
      v_DNNValue := f_NG_GetDNNForIMS(p_PLMN);
    } else {
      v_DNNValue := f_DomainName_Encode(f_GetDNNStringFromPICS(p_PDUType));
    }
    return cs_DNN(-, v_DNNValue);
  }
  
  /*
   * @desc      function to get PDN Type from p_DNN
   * @param     p_DNN
   * @return    PDU_PDN_DNN_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_GetPDNTypeFromDNN(template (omit) DNN p_DNN) return PDU_PDN_DNN_Type
  {
    var PDU_PDN_DNN_Type v_PDUType;

    if (ispresent(p_DNN)) {
      v_PDUType := f_GetPDN_DNNTypeFromAPN (valueof(p_DNN.dnnValue));
    } else { // APN/DNN not present so check what to use as default
      v_PDUType := f_GetDefaultAPN_DNNType_FromPICS();
    }

    return v_PDUType;
  }
  
  /*
   * @desc      Get the PDU Session which uses a particular DNN
   * @param     p_PDUSessionInfo
   * @param     p_DNNType
   * @return    template (omit) GSM_MobilityInfo_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT)
   */
  function f_Get_PDUSessionForDNNType(PDUSessionInfoList_Type p_PDUSessionInfo, template (present) PDU_PDN_DNN_Type p_DNNType) return template (omit) GSM_MobilityInfo_Type
  {
   var GSM_MobilityInfo_Type v_GSM_MobilityInfo;
   var integer i;
   
   for (i :=0; i < lengthof(p_PDUSessionInfo); i := i+1) { // @sic R5s200548 sic@
     v_GSM_MobilityInfo := p_PDUSessionInfo[i];
     if (match (v_GSM_MobilityInfo.PDUType, p_DNNType)) { // @sic R5-206296 sic@
         return v_GSM_MobilityInfo;
     }
   }
    return omit;
 }

  /*
   * @desc      Get the DNN for PDU Session id
   * @param     p_PDUSessionInfo
   * @param     p_PDUSessionId
   * @return    template (omit) DNN
   * @status    APPROVED (NR5GC)
   */
  function f_Get_DNNForPDUSessionId(PDUSessionInfoList_Type p_PDUSessionInfo, O1_Type p_PDUSessionId) return template (omit) DNN
  {
   var GSM_MobilityInfo_Type v_GSM_MobilityInfo;
   var integer i;
   
   for (i :=0; i < lengthof(p_PDUSessionInfo); i := i+1) {
     v_GSM_MobilityInfo := p_PDUSessionInfo[i];
     if (match (v_GSM_MobilityInfo.SessionId, p_PDUSessionId)) {  // @sic R5s200564 sic@
       return v_GSM_MobilityInfo.DNN;
     }
   }
   return omit;
 }

  /*
   * @desc      Get the PDN Index for PDU Session id
   * @param     p_PDUSessionInfo
   * @param     p_PDUSessionId
   * @return    template (omit) PDN_Index_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_PDN_IndexForPDUSessionId(PDUSessionInfoList_Type p_PDUSessionInfo, O1_Type p_PDUSessionId) return template (omit) PDN_Index_Type
  {
   var GSM_MobilityInfo_Type v_GSM_MobilityInfo;
   var integer i;
   
   for (i :=0; i < lengthof(p_PDUSessionInfo); i := i+1) {
     v_GSM_MobilityInfo := p_PDUSessionInfo[i];
     if (match (v_GSM_MobilityInfo.SessionId, p_PDUSessionId)) {
       return v_GSM_MobilityInfo.PdnIndex;
     }
   }
   return omit;
 }

  /*
   * @desc      Get the PDU Session Id which uses a particular DNN
   * @param     p_PDUSessionInfo
   * @param     p_DNNType
   * @return    integer
   * @status    APPROVED (NR5GC)
   */
  function f_Get_PDUSessionIdForDNNType(PDUSessionInfoList_Type p_PDUSessionInfo, template (present) PDU_PDN_DNN_Type p_DNNType) return integer
  {
   var GSM_MobilityInfo_Type v_GSM_MobilityInfo;
   var integer i;
   
   for (i :=0; i < lengthof(p_PDUSessionInfo); i := i+1) { // @sic R5s200548 sic@
     v_GSM_MobilityInfo := p_PDUSessionInfo[i];
     if (match (v_GSM_MobilityInfo.PDUType, p_DNNType)) { // @sic R5-206296 sic@
       return oct2int(v_GSM_MobilityInfo.SessionId);  // @sic R5s200564 sic@
     }
   }
    return -1;
 }

  /*
   * @desc      build the PDU SESSION AUTHENTICATION COMMAND, Piggybacked into the DL NAS Transport
   * @param     p_SecurityParams    (by reference)
   * @param     p_GSM_MobilityInfo
   * @param     p_PLMN
   * @param     p_BackOff           (default value: omit)
   * @param     p_Identity  (default value:  := px_IMSI_Def)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_PDUSessionAuthenticationCmd(inout NG_NAS_SecurityParams_Type p_SecurityParams,
                                             GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                             NAS_PlmnId p_PLMN,
                                             template (omit) GPRS_Timer3 p_BackOff := omit,
                                             hexstring p_Identity := px_IMSI_Def) return template (value) NG_NAS_DL_Pdu_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_GSMMsg;
    var template (value) EAP_Message v_EAP;

    // Evaluate Authentication parameters and generate new keys
    p_SecurityParams := f_NG_EAP_AuthenticationInit(p_SecurityParams, p_PLMN, hex2str(p_Identity)); // @sic R5s230215 sic@
    v_EAP := cs_EAP_Message (f_NG_EAP_ChallengeReq (p_SecurityParams, p_PLMN), omit); // @sic R5s201382 sic@
    v_GSMMsg := cs_NG_PDU_SESSION_AUTHENTICATION_COMMAND (cs_NG_PDU_SessionId(p_GSM_MobilityInfo.SessionId, omit), // @sic R5s00564 sic
                                                          tsc_PTI_Unassigned,
                                                          v_EAP,
                                                          omit);
    return f_Get_NG_DLNASTransport (cs_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                    v_GSMMsg,
                                    -,
                                    p_GSM_MobilityInfo.SessionId, // @sic R5s190626, R5s200564 sic@
                                    omit,
                                    omit,
                                    p_BackOff);  }

  /*
   * @desc      Check the PDU SESSION AUTHENTICATION COMPLETE, Piggybacked into the UL NAS Transport
   * @param     p_GSM_MobilityInfo
   * @param     p_SecurityParams
   * @param     p_ReceivedMsgs
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_PDUSessionAuthenticationComplete(GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                                       NG_NAS_SecurityParams_Type p_SecurityParams,
                                                       NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                                       template S_NSSAI_Type p_S_NSSAI := *,
                                                       template DNN p_DNN := *,
                                                       template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                                       template ReleaseAssistanceInd p_ReleaseAssistanceInd := *) return boolean
  {
    var boolean v_Result := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    // Check NAS Transport msg first
    if (not f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_GSM_MobilityInfo.SessionId,
                                           omit,
                                           omit,
                                           p_S_NSSAI,
                                           p_DNN,
                                           omit,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd)) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_PDU_SESSION_AUTHENTICATION_COMPLETE (cr_NG_PDU_SessionId(-, p_GSM_MobilityInfo.SessionId), // @sic R5s00564 sic@
                                                                           tsc_PTI_Unassigned,
                                                                           cr_EAP_Message(omit),
                                                                           cr_ExtdPCOAny ifpresent))) {
      // Check received EAP Msg
      v_Result := f_NG_EAP_SuccessfulAuthenticationResponse(p_SecurityParams, v_GSMMsg.pdu_Session_Authentication_Complete.eapMessage.eapMsg);
    }
    return v_Result;
  }

  /*
   * @desc      build the PDU SESSION AUTHENTICATION RESULT, Piggybacked into the DL NAS Transport
   * @param     p_GSM_MobilityInfo
   * @param     p_EAP
   * @param     p_BackOff           (default value: omit)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (NR5GC)
   */
  function f_Get_PDUSessionAuthenticationResult(GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                             template (value) EAP_Message p_EAP,
                                             template (omit) GPRS_Timer3 p_BackOff := omit) return template (value) NG_NAS_DL_Pdu_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_GSMMsg;

    v_GSMMsg := cs_NG_PDU_SESSION_AUTHENTICATION_RESULT (cs_NG_PDU_SessionId(p_GSM_MobilityInfo.SessionId, omit), // @sic R5s00564 sic@
                                                         tsc_PTI_Unassigned,
                                                         p_EAP,
                                                         omit);
    return f_Get_NG_DLNASTransport (cs_PayloadContainerType(tsc_PayloadContainerESMMsg),
                                    v_GSMMsg,
                                    -,
                                    p_GSM_MobilityInfo.SessionId,
                                    omit,
                                    omit,
                                    p_BackOff);
  }

  /*
   * @desc      build the PDU SESSION ESTABLISHMENT ACCEPT, Piggybacked into the DL NAS Transport
   * @param     p_GSM_MobilityInfo
   * @param     p_GMM_MobilityInfo
   * @param     p_DNN
   * @param     p_SSC_Mode          (default value: crs_SSC_Mode(-, '001'B)
   * @param     p_Session_AMBR      (default value: cs_Session_AMBR ('06'O, '05'O, '0004'O, '05'O, '0004'O)
   * @param     p_PDU_SessionType   (default value: omit)
   * @param     p_Cause             (default value: omit)
   * @param     p_RQTimer           (default value: omit)
   * @param     p_S_NSSAI           (default value: cs_S_NSSAI_SST1eMBB_WithIEI)
   * @param     p_AlwaysOnPDUSessionInd (default value: omit)
   * @param     p_EAP               (default value: omit)
   * @param     p_QoS_Rules         (default value: omit)
   * @param     p_QoSFlowDescr      (default value: omit)
   * @param     p_ExtdPCO           (default value: omit)
   * @param     p_BackOff           (default value: omit)
   * @param     p_BuildQosFlow      (default value: omit) set to required value if a specific QoSFlow must be built (with interworkingWithEPS parameters)
   * @param     p_InterworkWithEPS  (default value: true) only set to false when called from f_MultipleQoSPreamble_Part2
   * @param     p_NGSM_NtwkFeatSupport           (default value: omit)
   * @param     p_ServingPLMNRateCtrl           (default value: omit)
   * @param     p_ATSSSContainer           (default value: omit)
   * @param     p_ControlPlaneInd           (default value: omit)
   * @param     p_IPHeaderCompConfig           (default value: omit)
   * @param     p_EthernetHeaderCompConfig           (default value: omit)
   * @param     p_ExtraPDN_Address           (default value: omit)
   * @param     p_ServiceLvlAA           (default value: omit)
   * @param     p_ReceivedMBS           (default value: omit)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_PDUSessionEstablishmentAccept(GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                                  GMM_MobilityInfo_Type p_GMM_MobilityInfo,
                                                  template (value) DNN p_DNN,       // @sic R5-205939 sic@
                                                  template (value) SSC_Mode p_SSC_Mode := crs_SSC_Mode(-, '001'B),
                                                  template (value) Session_AMBR p_Session_AMBR := cs_Session_AMBR ('06'O, '05'O, '0004'O, '05'O, '0004'O),
                                                  template (omit) PDU_SessionType p_PDU_SessionType := omit,
                                                  template (omit) GMM_GSM_Cause p_Cause := omit,
                                                  template (omit) GPRS_Timer p_RQTimer := omit,
                                                  template (omit) S_NSSAI_Type p_S_NSSAI := omit, // @sic R5s190919, R5-211168 sic@
                                                  template (omit) AlwaysOnPDUSessionInd p_AlwaysOnPDUSessionInd := omit,
                                                  template (omit) EAP_Message p_EAP := omit,
                                                  template (omit) QoS_Rules p_QoS_Rules := omit,
                                                  template (omit) QoSFlowDescr p_QoSFlowDescr := omit,
                                                  template (omit) ExtdProtocolConfigOptions p_ExtdPCO := omit,
                                                  template (omit) GPRS_Timer3 p_BackOff := omit,
                                                  template (omit) charstring p_BuildQosFlow := omit,
                                                  boolean p_InterworkWithEPS := true,
                                                  template (omit) NGSM_NetworkFeatureSupport p_NGSM_NtwkFeatSupport := omit, // @sic R5s201387 Baseline Moving sic@
                                                  template (omit) ServingPLMNRateControl p_ServingPLMNRateCtrl := omit,
                                                  template (omit) ATSSSContainer p_ATSSSContainer := omit,
                                                  template (omit) ControlPlaneInd p_ControlPlaneInd := omit,
                                                  template (omit) IPHeaderCompressionConfig p_IPHeaderCompConfig := omit,
                                                  template (omit) EthernetHeaderCompressConfig p_EthernetHeaderCompConfig := omit,
                                                  template (omit) PDN_AddressInfo_Type p_ExtraPDN_Address := omit,
                                                  template (omit) ServiceLvlAAContainer p_ServiceLvlAA := omit,
                                                  template (omit) ReceivedMBSContainer p_ReceivedMBS := omit) return template (value) NG_NAS_DL_Pdu_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_GSMMsg;
    var template (value) PDU_SessionType v_PDU_SessionType;
    var B3_Type v_PDN_TypeToBeUsed;
    var ListOfPDN_AddressInfo_Type v_PDN_Addresses := {};
    var template (omit) PDU_Address v_PDU_Address := omit;
    var template (omit) AlwaysOnPDUSessionInd v_AlwaysOn := omit;
    var template (value) QoS_Rules v_QoS_Rules := f_BuildDefaultQoSRules ("1"); // @sic R5-202585 sic@
    var template (value) QoSFlowDescr v_QoSFlowDescr;
    var template (omit) ExtdProtocolConfigOptions v_ExtdPCO;
    var template (omit) MappedEPSBearerContexts v_MappedEPSBearerContexts := omit;
    var template (value) MappedEPSContext v_MappedEPSContext;
    var bitstring v_EPSParam; // If used
    var O1_Type v_EPSBearerId := '00'O; // If used
    var boolean v_InterworkWithEPS := false;
    var template (value) QoS_Flow v_QoS_Flow;
    var octetstring v_ParamOctets;
    var template (value) S_NSSAI_Type v_S_NSSAI;
    
    if (isvalue(p_PDU_SessionType)) {
      v_PDU_SessionType := valueof(p_PDU_SessionType);
    } else {
      v_PDU_SessionType := cs_PDU_SessionType (p_GSM_MobilityInfo.SessionType);
    }
        
    if (isvalue(p_GMM_MobilityInfo.GMMCap) and p_InterworkWithEPS) { // @sic R5s190464 R5s191172, R5s201367 sic@
      if (p_GMM_MobilityInfo.GMMCap.s1Cap == '1'B) { // @sic R5-195328 sic@
        v_InterworkWithEPS := true;
        if (isvalue(p_GSM_MobilityInfo.EPS_Bearer)) { // @sic R5-204400 sic@
          v_EPSBearerId := hex2oct(int2hex(valueof(p_GSM_MobilityInfo.EPS_Bearer), 1) & '0'H);
        } else {
          FatalError(__FILE__, __LINE__, "EPS Supported but no bearer id calculated");
        }
        if (p_GSM_MobilityInfo.PDUType == IMS_DNN) {    // @sic R5-205939 sic@
          v_EPSParam := encvalue(f_Get_508_EPSQoS(DEF_2));
        } else {
          v_EPSParam := encvalue(f_Get_508_EPSQoS(DEF_1));
        }
        v_ParamOctets := bit2oct(v_EPSParam); // @sic R5s210302 sic@
        // This is only correct if the mappedEPSContext contains EPSQoS
        v_MappedEPSContext := cs_OneMappedEPSContext(v_EPSBearerId, lengthof(v_ParamOctets), cs_EPSParameter_QoS(v_ParamOctets)); // @sic R5s210302 sic@
        v_MappedEPSBearerContexts := cs_OneMappedEPSBearerContextList (v_MappedEPSContext);
      }
    }
    
    if (isvalue(p_QoS_Rules)) {
      v_QoS_Rules := valueof(p_QoS_Rules);
    } else {
      select(p_GSM_MobilityInfo.PDUType) {  // @sic R5-221467 sic@
        case (IMS_DNN) {    // @sic R5-205939 sic@
          v_QoS_Rules := f_BuildDefaultQoSRules ("2"); // @sic R5-202585 sic@
        }
        case (URLLC_DNN) { // @sic R5-221467 sic@
          v_QoS_Rules := f_BuildDefaultQoSRules ("8");
       }
     }
    } // else use QoS 1 already defined above
    
    if (isvalue(p_QoSFlowDescr)) { // @sic R5-194896 sic@
      v_QoSFlowDescr := valueof(p_QoSFlowDescr);
    } else {
      if (isvalue(p_BuildQosFlow)) { // @sic R5-202550 sic@
        // need to build a specific QoS flow
        v_QoS_Flow := f_BuildDefaultQosFlow(valueof(p_BuildQosFlow), v_InterworkWithEPS, v_EPSBearerId);
      } else {
        select(p_GSM_MobilityInfo.PDUType) {  // @sic R5-221467 sic@
          case (IMS_DNN) {    // @sic R5-205939 sic@
            v_QoS_Flow := cs_QoS_Flow2(v_InterworkWithEPS, v_EPSBearerId); // @sic R5-204400, R5s201323 sic@
          }
          case (URLLC_DNN) { // @sic R5-221467 sic@
            v_QoS_Flow := f_BuildDefaultQosFlow ("7");
          } case else {
            v_QoS_Flow := cs_QoS_Flow1(v_InterworkWithEPS, v_EPSBearerId); // @sic R5-204400, R5s201323 sic@
          }
        }
      }
      v_QoSFlowDescr := cs_QoSFlowDescr ({v_QoS_Flow}); // @sic R5s220471 sic@
    }
    
    if (isvalue(p_S_NSSAI)) { // @sic R5-211168 sic@
      v_S_NSSAI := p_S_NSSAI; // compiler warning may be ignored due to check
    } else {
      // 38.508-1 table 4.8.4-1 specifies SST_eMMB for both Config#1 and #2, but there is currently no other option
      // This to be updated when another Config is specified. FFS
      select (p_GSM_MobilityInfo.PDUType) {  // @sic R5s221179 sic@
       case (URLLC_DNN, Ethernet_DNN) {      // @sic R5-227473 sic@
         v_S_NSSAI := cs_S_NSSAI_WithIEI('22'O, cs_S_NSSAI_SST2_URLLC);
       }
       case (MIOT_DNN) {
         v_S_NSSAI := cs_S_NSSAI_WithIEI('22'O, cs_S_NSSAI_SST3_MIoT);
       }
       case (V2X_DNN) {
         v_S_NSSAI := cs_S_NSSAI_WithIEI('22'O, cs_S_NSSAI_SST4_V2X);
       }
       case else {
        v_S_NSSAI := cs_S_NSSAI_SST1eMBB_WithIEI;
       }
      }
    }
    
    if (isvalue(p_AlwaysOnPDUSessionInd)) {
      v_AlwaysOn := p_AlwaysOnPDUSessionInd;
    } else if (isvalue(p_GSM_MobilityInfo.AlwaysOn)) {
      v_AlwaysOn := cs_AlwaysOnNotAllowed;
    if (match(p_GSM_MobilityInfo.PDUType, (URLLC_DNN, Ethernet_DNN))) { // @sic R5s221179, R5-227473 sic@
        v_AlwaysOn := cs_AlwaysOnAllowed;
      }
    }
    
    v_PDN_TypeToBeUsed := valueof(v_PDU_SessionType.typeValue);
    select (v_PDN_TypeToBeUsed){
      case (tsc_PdnType_IPv4, tsc_PdnType_IPv6, tsc_PdnType_IPv4v6) {
        v_PDN_Addresses[0] := f_PDN_AddressInfo_Get (f_NR5GC_GetPdnIndex(p_GSM_MobilityInfo)); // @sic R5s200643 sic@
        v_PDU_Address := f_NG_GetPDNAddress(f_CheckExtdPCOforIPallocationViaNas(p_GSM_MobilityInfo.PCO), v_PDN_TypeToBeUsed, v_PDN_Addresses[0]); //  @sic R5s200571, R5s200643 sic@
      }
    }
    
    if (isvalue(p_ExtdPCO)) {
      v_ExtdPCO := p_ExtdPCO;
    } else {
      if (isvalue(p_ExtraPDN_Address)) { // @sic R5-213400, R5-217830 sic@
        v_PDN_Addresses[1] := valueof(p_ExtraPDN_Address);
      }
      v_ExtdPCO := f_NG_GetDefaultExtdProtocolConfigOptions (p_GSM_MobilityInfo.PCO, v_PDN_Addresses); // @sic R5s200643, R5-213400 sic@
    }
    
    v_GSMMsg := cs_NG_PDU_SESSION_ESTABLISHMENT_ACCEPT (cr_NG_PDU_SessionId(-, p_GSM_MobilityInfo.SessionId), // @sic R5s00564 sic@
                                                        p_GSM_MobilityInfo.PTI,
                                                        p_SSC_Mode,
                                                        v_PDU_SessionType,
                                                        v_QoS_Rules,
                                                        p_Session_AMBR,
                                                        p_Cause,
                                                        v_PDU_Address,
                                                        p_RQTimer,
                                                        v_S_NSSAI,
                                                        v_AlwaysOn,
                                                        v_MappedEPSBearerContexts, // @sic R5-195328 sic@
                                                        p_EAP,
                                                        v_QoSFlowDescr,
                                                        v_ExtdPCO,
                                                        p_DNN,                    // @sic R5-205939 sic@
                                                        p_NGSM_NtwkFeatSupport,   // @sic R5s201387 Baseline Moving sic@
                                                        p_ServingPLMNRateCtrl,
                                                        p_ATSSSContainer,
                                                        p_ControlPlaneInd,
                                                        p_IPHeaderCompConfig,
                                                        p_EthernetHeaderCompConfig,
                                                        p_ServiceLvlAA,           // @sic R5s221179 Baseline Moving sic@
                                                        p_ReceivedMBS);
    return f_Get_NG_DLNASTransport (cs_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                    v_GSMMsg,
                                    -,
                                    p_GSM_MobilityInfo.SessionId,  // @sic R5s190338, R5s190626, R5s200564 sic@
                                    omit,
                                    omit,
                                    p_BackOff);
  }

  /*
   * @desc      Check the PDU SESSION RELEASE REQUEST, Piggybacked into the UL NAS Transport
   * @param     p_GSM_MobilityInfo  (by reference)
   * @param     p_PDUSessionGlobalInfo
   * @param     p_ReceivedMsgs
   * @param     p_PDU_SessionId
   * @param     p_PTI               (default value: ?)
   * @param     p_Cause             (default value: *)
   * @param     p_ExtdPCO           (default value: *)
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: *)
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_PDUSessionReleaseReq( out GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                            PDUSessionInfoList_Type p_PDUSessionGlobalInfo,
                                            NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                            template (present) O1_Type p_PDU_SessionId,
                                            template (present) ProcedureTransactionIdentifier p_PTI := ?,
                                            template GMM_GSM_Cause p_Cause := *,
                                            template ExtdProtocolConfigOptions p_ExtdPCO := *,
                                            template NG_PDU_SessionId p_OldPDU_SessionId  := *,
                                            template NG_Request_Type p_RequestType  := *,
                                            template S_NSSAI_Type p_S_NSSAI  := *,
                                            template DNN p_DNN  := *,
                                            template AdditionalInformation p_AdditionalInfo  := *,
                                            template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                            template ReleaseAssistanceInd p_ReleaseAssistanceInd := *) return boolean
  {
    var boolean v_Result := false;
    var boolean v_ExistingId := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    var integer i;
    
    // Check NAS Transport msg first
    v_Result := f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_PDU_SessionId,
                                           p_OldPDU_SessionId,
                                           p_RequestType,
                                           p_S_NSSAI,
                                           p_DNN,
                                           p_AdditionalInfo,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd);
    if (not v_Result) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_PDU_SESSION_RELEASE_REQUEST (cr_NG_PDU_SessionId(-, p_PDU_SessionId), // @sic R5s200564 sic@
                                                                   p_PTI,
                                                                   p_Cause,
                                                                   p_ExtdPCO))) {
      v_Result := true;
    } else {  // @sic R5s190944 sic@
      return false;  // @sic R5s220989 sic@
    }
    // Default message contents specifies this must match an existing session establishment id
    for (i := 0; i < lengthof(p_PDUSessionGlobalInfo); i := i+1) {
     if (match (v_GSMMsg.pdu_Session_Release_Request.pduSessionId.sessionId, p_PDUSessionGlobalInfo[i].SessionId)) {
       v_ExistingId := true;
     }
    }
    if (not v_ExistingId) {
      v_Result := v_ExistingId;
    }
    
    // Store info for this release
    p_GSM_MobilityInfo.SessionId := v_GSMMsg.pdu_Session_Release_Request.pduSessionId.sessionId; // @sic R5s200564 sic@
    p_GSM_MobilityInfo.PTI := v_GSMMsg.pdu_Session_Release_Request.procedureTransactionIdentifier;
    p_GSM_MobilityInfo.SessionType := omit;
    p_GSM_MobilityInfo.EPS_Bearer := omit; // @sic R5s201533 sic@
    p_GSM_MobilityInfo.PdnIndex := omit; // @sic R5s201533 sic@
    
    if (ispresent (p_ReceivedMsgs.Msg.ul_Nas_Transport.dnn)) {
      p_GSM_MobilityInfo.DNN := p_ReceivedMsgs.Msg.ul_Nas_Transport.dnn;
    } else {
      p_GSM_MobilityInfo.DNN := omit;
    }
    p_GSM_MobilityInfo.PDUType := f_GetPDNTypeFromDNN(p_GSM_MobilityInfo.DNN);  // @sic R5-206296 sic@
    p_GSM_MobilityInfo.AlwaysOn := omit;

    if (ispresent (v_GSMMsg.pdu_Session_Release_Request.extdProtocolConfigurationOptions)) {
      p_GSM_MobilityInfo.PCO := v_GSMMsg.pdu_Session_Release_Request.extdProtocolConfigurationOptions;
    } else {
      p_GSM_MobilityInfo.PCO := omit;
    }
    p_GSM_MobilityInfo.NSSAI := omit; // @sic R5s210408 sic@
    return v_Result;
  }

  /*
   * @desc      build the PDU SESSION RELEASE COMMAND, Piggybacked into the DL NAS Transport
   * @param     p_PDU_SessionId
   * @param     p_Cause             (default value: cs_GMM_GSM_Cause (omit, '00011010'B)
   * @param     p_BackOff           (default value: omit)
   * @param     p_NGSM_CongestionReattemptInd (default value: omit)
   * @param     p_ExtdPCO           (default value: omit)
   * @param     p_EAP               (default value: omit)
   * @param     p_PTI               (default value: '00'O)
   * @param     p_AccessType               (default value: '00'O)
   * @param     p_ServiceLvlAA               (default value: '00'O)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_PDUSessionReleaseCommand(template (value) O1_Type p_PDU_SessionId,
                                             template (value) GMM_GSM_Cause p_Cause := cs_GMM_GSM_Cause (omit, '00011010'B),
                                             template (omit) GPRS_Timer3 p_BackOff := omit,
                                             template (omit) NGSM_CongestionReattemptInd p_NGSM_CongestionReattemptInd := omit, // @sic R5s190543 sic@,
                                             template (omit) ExtdProtocolConfigOptions p_ExtdPCO := omit,
                                             template (omit) EAP_Message p_EAP := omit,
                                             ProcedureTransactionIdentifier p_PTI := '00'O,
                                             template (omit) AccessType p_AccessType := omit,
                                             template (omit) ServiceLvlAAContainer p_ServiceLvlAA := omit) return template (value) NG_NAS_DL_Pdu_Type // @sic R5s201063 sic@,
  {
    var template (value) NG_NAS_DL_Message_Type v_GSMMsg;
       
    v_GSMMsg := cs_NG_PDU_SESSION_RELEASE_COMMAND (cs_NG_PDU_SessionId (p_PDU_SessionId, omit), // @sic R5s200564 sic@
                                                   p_PTI,
                                                   p_Cause,
                                                   p_BackOff,
                                                   p_EAP,
                                                   p_NGSM_CongestionReattemptInd,
                                                   p_ExtdPCO,
                                                   p_AccessType,       // @sic R5s201387 Baseline Moving sic@
                                                   p_ServiceLvlAA);    // @sic R5s221179 Baseline Moving sic@
    return f_Get_NG_DLNASTransport (cs_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                    v_GSMMsg,
                                    -,
                                    p_PDU_SessionId, // @sic R5s190626, R5s200564 sic@
                                    omit,
                                    omit,
                                    p_BackOff);
  }

  /*
   * @desc      Check the PDU SESSION RELEASE COMPLETE, Piggybacked into the UL NAS Transport
   * @param     p_PDUSessionGlobalInfo (by reference)
   * @param     p_ReceivedMsgs
   * @param     p_PDU_SessionId
   * @param     p_PTI               (default value: ?)
   * @param     p_Cause             (default value: *)
   * @param     p_ExtdPCO           (default value: *)
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: *)
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_PDUSessionReleaseComplete( inout PDUSessionInfoList_Type p_PDUSessionGlobalInfo,
                                                 NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                                 template (present) O1_Type p_PDU_SessionId,
                                                 template (present) ProcedureTransactionIdentifier p_PTI := ?,
                                                 template GMM_GSM_Cause p_Cause := *,
                                                 template ExtdProtocolConfigOptions p_ExtdPCO := *,
                                                 template NG_PDU_SessionId p_OldPDU_SessionId  := *,
                                                 template NG_Request_Type p_RequestType  := *,
                                                 template S_NSSAI_Type p_S_NSSAI  := *,
                                                 template DNN p_DNN  := *,
                                                 template AdditionalInformation p_AdditionalInfo  := *,
                                                 template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                                 template ReleaseAssistanceInd p_ReleaseAssistanceInd := *) return boolean
  {
    var boolean v_Result := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    var PDUSessionInfoList_Type v_NewList := {}; // @sic R5s190626 sic@
    var integer i;
    var integer j := 0;
    
    // Check NAS Transport msg first
    v_Result := f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_PDU_SessionId,
                                           p_OldPDU_SessionId,
                                           p_RequestType,
                                           p_S_NSSAI,
                                           p_DNN,
                                           p_AdditionalInfo,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd);
    if (not v_Result) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_PDU_SESSION_RELEASE_COMPLETE (cr_NG_PDU_SessionId(-, p_PDU_SessionId), // @sic R5s200564 sic@
                                                                   p_PTI,
                                                                   p_Cause,
                                                                   p_ExtdPCO))) {
      v_Result := true;
    } else {  // @sic R5s190944 sic@
      v_Result := false;
    }
    // Delete any stored info for this Session Id as it's now released
    for (i := 0; i < lengthof(p_PDUSessionGlobalInfo); i := i+1) { // @sic R5s190388 sic@
      if (not (v_GSMMsg.pdu_Session_Release_Complete.pduSessionId.sessionId == p_PDUSessionGlobalInfo[i].SessionId)) { // @sic R5s190388, R5s200564 sic@
        v_NewList[j] := p_PDUSessionGlobalInfo[i];
        j := j+ 1;
      }
    }
    
    p_PDUSessionGlobalInfo := v_NewList;
    
    return v_Result;
  }

   /*
   * @desc      Check the PDU SESSION MODIFICATION REQUEST, Piggybacked into the UL NAS Transport
   * @param     p_GSM_MobilityInfo  (by reference)
   * @param     p_PDUSessionGlobalInfo
   * @param     p_ReceivedMsgs
   * @param     p_PDU_SessionId     (default value: ?)
   * @param     p_PTI               (default value: ?)
   * @param     p_NG_UE_SM_Cap      (default value: *)
   * @param     p_Cause             (default value: *)
   * @param     p_MaxNumPacketFilters (default value: *)
   * @param     p_AlwaysOnPDUSessionReq (default value: *)
   * @param     p_IntegrityProtMaxDataRate (default value: *)
   * @param     p_QoS_Rules         (default value: *)
   * @param     p_QoSFlowDescr      (default value: *)
   * @param     p_MappedEPSBearerContexts (default value: *)
   * @param     p_ExtdPCO           (default value: *)
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: *)
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @param     p_PortManagementInfoContainer (default value: *)
   * @param     p_IPHeaderCompConfig (default value: *)
   * @param     p_EthernetHeaderCompConfig (default value: *)
   * @param     p_RequestedMBS (default value: *)
   * @param     p_ServiceLvlAA (default value: *)
   * @return    boolean
   * @status    APPROVED (NR5GC, NR5GC_IRAT)
   */
  function f_Check_NG_PDUSessionModificationReq( out GSM_MobilityInfo_Type p_GSM_MobilityInfo,
                                                 PDUSessionInfoList_Type p_PDUSessionGlobalInfo,
                                                 NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                                 template (present) O1_Type p_PDU_SessionId := ?,
                                                 template (present) ProcedureTransactionIdentifier p_PTI := ?,
                                                 template NG_UE_SM_Cap p_NG_UE_SM_Cap := *,
                                                 template GMM_GSM_Cause p_Cause := *,
                                                 template MaxNumPacketFilters p_MaxNumPacketFilters := *,
                                                 template AlwaysOnPDUSessionReq p_AlwaysOnPDUSessionReq := *,
                                                 template IntegrityProtMaxDataRate p_IntegrityProtMaxDataRate := *,
                                                 template QoS_Rules p_QoS_Rules := *,
                                                 template QoSFlowDescr p_QoSFlowDescr := *,
                                                 template MappedEPSBearerContexts p_MappedEPSBearerContexts := *,
                                                 template ExtdProtocolConfigOptions p_ExtdPCO := *,
                                                 template NG_PDU_SessionId p_OldPDU_SessionId  := *,
                                                 template NG_Request_Type p_RequestType  := *,
                                                 template S_NSSAI_Type p_S_NSSAI  := *,
                                                 template DNN p_DNN  := *,
                                                 template AdditionalInformation p_AdditionalInfo  := *,
                                                 template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                                 template ReleaseAssistanceInd p_ReleaseAssistanceInd := *,
                                                 template PortManagementInfoContainer p_PortManagementInfoContainer := *,
                                                 template IPHeaderCompressionConfig p_IPHeaderCompConfig := *,
                                                 template EthernetHeaderCompressConfig p_EthernetHeaderCompConfig := *,
                                                 template RequestedMBSContainer p_RequestedMBS := *,
                                                 template ServiceLvlAAContainer p_ServiceLvlAA := *) return boolean
  {
    var boolean v_Result := false;
    var boolean v_ExistingId := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    var integer i;
    
    // Check NAS Transport msg first
    v_Result := f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_PDU_SessionId,
                                           p_OldPDU_SessionId,
                                           p_RequestType,
                                           p_S_NSSAI,
                                           p_DNN,
                                           p_AdditionalInfo,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd);
    if (not v_Result) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_PDU_SESSION_MODIFICATION_REQUEST (cr_NG_PDU_SessionId(-, p_PDU_SessionId), // @sic R5s200564 sic@
                                                                        p_PTI,
                                                                        p_NG_UE_SM_Cap,
                                                                        p_Cause,
                                                                        p_MaxNumPacketFilters,
                                                                        p_AlwaysOnPDUSessionReq,
                                                                        p_IntegrityProtMaxDataRate,
                                                                        p_QoS_Rules,
                                                                        p_QoSFlowDescr,
                                                                        p_MappedEPSBearerContexts,
                                                                        p_ExtdPCO,
                                                                        p_PortManagementInfoContainer,  // @sic R5s201387 Baseline Moving sic@
                                                                        p_IPHeaderCompConfig,
                                                                        p_EthernetHeaderCompConfig,
                                                                        p_RequestedMBS,        // @sic R5s221179 Baseline Moving sic@
                                                                        p_ServiceLvlAA))) {
      v_Result := true;
    } else {  // @sic R5s190944 sic@
      return false;  // @sic R5s220989 sic@
    }
    // Default message contents specifies this must match an existing session establishment id
    for (i := 0; i < lengthof(p_PDUSessionGlobalInfo); i := i+1) {
     if (match (v_GSMMsg.pdu_Session_Modification_Request.pduSessionId.sessionId, p_PDUSessionGlobalInfo[i].SessionId)) { // @sic R5s200564 sic@
       v_ExistingId := true;
       p_GSM_MobilityInfo := p_PDUSessionGlobalInfo[i]; // @sic R5s220577 sic@
     }
    }
    if (not v_ExistingId) {
      v_Result := v_ExistingId;
    }
    
    // Store info for this modification
    p_GSM_MobilityInfo.SessionId := v_GSMMsg.pdu_Session_Modification_Request.pduSessionId.sessionId; // @sic R5s200564 sic@
    p_GSM_MobilityInfo.PTI := v_GSMMsg.pdu_Session_Modification_Request.procedureTransactionIdentifier;
    p_GSM_MobilityInfo.SessionType := omit;
    p_GSM_MobilityInfo.EPS_Bearer := omit; // @sic R5s201533 sic@
    p_GSM_MobilityInfo.PdnIndex := omit; // @sic R5s201533 sic@
   
    // @sic R5s220577 sic@
    if (ispresent (p_ReceivedMsgs.Msg.ul_Nas_Transport.dnn)) {
      p_GSM_MobilityInfo.DNN := p_ReceivedMsgs.Msg.ul_Nas_Transport.dnn;
      p_GSM_MobilityInfo.PDUType := f_GetPDNTypeFromDNN(p_GSM_MobilityInfo.DNN);  // @sic R5-206296 sic@
    }
    if (ispresent (v_GSMMsg.pdu_Session_Modification_Request.alwaysOnPDUSessionReq)) {
      p_GSM_MobilityInfo.AlwaysOn := v_GSMMsg.pdu_Session_Modification_Request.alwaysOnPDUSessionReq;
    }
    if (ispresent (v_GSMMsg.pdu_Session_Modification_Request.extdProtocolConfigurationOptions)) {
      p_GSM_MobilityInfo.PCO := v_GSMMsg.pdu_Session_Modification_Request.extdProtocolConfigurationOptions;
    }
    return v_Result;
  }

  /*
   * @desc      build the PDU SESSION MODIFICATION COMMAND, Piggybacked into the DL NAS Transport
   * @param     p_PDU_SessionId
   * @param     p_GSM_MobilityInfo  (default value: omit)
   * @param     p_Cause             (default value: omit)
   * @param     p_Session_AMBR      (default value: omit)
   * @param     p_RQTimer           (default value: omit)
   * @param     p_AlwaysOnPDUSessionInd (default value: omit)
   * @param     p_QoS_Rules         (default value: omit)
   * @param     p_QoSFlowDescr      (default value: omit)
   * @param     p_MappedEPSBearerContexts (default value: omit)
   * @param     p_ExtdPCO           (default value: omit)
   * @param     p_ATSSSContainer    (default value: omit)
   * @param     p_IPHeaderCompConfig (default value: omit)
   * @param     p_PortManagementInfoContainer (default value: omit)
   * @param     p_ServingPLMNRateCtrl (default value: omit)
   * @param     p_EthernetHeaderCompConfig (default value: omit)
   * @param     p_ReceivedMBS (default value: omit)
   * @param     p_ServiceLvlAA (default value: omit)
   * @param     p_BackOff           (default value: omit)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT)
   */
  function f_Get_NG_PDUSessionModificationCommand(template (value) O1_Type p_PDU_SessionId,
                                                  template (omit) GSM_MobilityInfo_Type p_GSM_MobilityInfo := omit,
                                                  template (omit) GMM_GSM_Cause p_Cause := omit,
                                                  template (omit) Session_AMBR p_Session_AMBR := omit,
                                                  template (omit) GPRS_Timer p_RQTimer := omit,
                                                  template (omit) AlwaysOnPDUSessionInd p_AlwaysOnPDUSessionInd := omit,
                                                  template (omit) QoS_Rules p_QoS_Rules := omit,
                                                  template (omit) QoSFlowDescr p_QoSFlowDescr := omit,
                                                  template (omit) MappedEPSBearerContexts p_MappedEPSBearerContexts := omit,
                                                  template (omit) ExtdProtocolConfigOptions p_ExtdPCO := omit,
                                                  template (omit) ATSSSContainer p_ATSSSContainer := omit,          // @sic R5s201387 Baseline Moving sic@
                                                  template (omit) IPHeaderCompressionConfig p_IPHeaderCompConfig := omit,
                                                  template (omit) PortManagementInfoContainer p_PortManagementInfoContainer := omit,
                                                  template (omit) ServingPLMNRateControl p_ServingPLMNRateCtrl := omit,
                                                  template (omit) EthernetHeaderCompressConfig p_EthernetHeaderCompConfig := omit,
                                                  template (omit) ReceivedMBSContainer p_ReceivedMBS := omit,
                                                  template (omit) ServiceLvlAAContainer p_ServiceLvlAA := omit,
                                                  template (omit) GPRS_Timer3 p_BackOff := omit) return template (value) NG_NAS_DL_Pdu_Type
  {
    var template (value) NG_NAS_DL_Message_Type v_GSMMsg;
    var template (value) O1_Type v_PDU_SessionId := p_PDU_SessionId;
    var ProcedureTransactionIdentifier v_PTI := '00'O;
    var template (omit) AlwaysOnPDUSessionInd v_AlwaysOn := omit;
       
    if (isvalue(p_GSM_MobilityInfo)) { // Modification was triggered by UE sending Request message
      v_PDU_SessionId := p_GSM_MobilityInfo.SessionId;
      v_PTI := valueof(p_GSM_MobilityInfo.PTI);
      if (isvalue(p_GSM_MobilityInfo.AlwaysOn)) {
        v_AlwaysOn := cs_AlwaysOnNotAllowed;
        if (valueof(p_GSM_MobilityInfo.PDUType) == URLLC_DNN) { // @sic R5s221179 sic@
          v_AlwaysOn := cs_AlwaysOnAllowed;
        }
      }
    }
    if (isvalue(p_AlwaysOnPDUSessionInd)) {
      v_AlwaysOn := p_AlwaysOnPDUSessionInd;
    }
      
    v_GSMMsg := cs_NG_PDU_SESSION_MODIFICATION_COMMAND (cs_NG_PDU_SessionId(v_PDU_SessionId, omit), // @sic R5s200564 sic@
                                                        v_PTI,
                                                        p_Cause,
                                                        p_Session_AMBR,
                                                        p_RQTimer,
                                                        v_AlwaysOn,
                                                        p_QoS_Rules,
                                                        p_QoSFlowDescr,
                                                        p_MappedEPSBearerContexts,
                                                        p_ExtdPCO,
                                                        p_ATSSSContainer,       // @sic R5s201387 Baseline Moving sic@
                                                        p_IPHeaderCompConfig,
                                                        p_PortManagementInfoContainer,
                                                        p_ServingPLMNRateCtrl,
                                                        p_EthernetHeaderCompConfig,
                                                        p_ReceivedMBS,              // @sic R5s221179 Baseline Moving sic@
                                                        p_ServiceLvlAA);            // @sic R5s221179 Baseline Moving sic@
    return f_Get_NG_DLNASTransport (cs_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                    v_GSMMsg,
                                    -,
                                    v_PDU_SessionId, // @sic R5s190626 sic@
                                    omit,
                                    omit,
                                    p_BackOff);
  }

  /*
   * @desc      Check the PDU SESSION MODIFICATION COMPLETE, Piggybacked into the UL NAS Transport
   * @param     p_ReceivedMsgs
   * @param     p_PDU_SessionId
   * @param     p_PTI               (default value: ?)
   * @param     p_ExtdPCO           (default value: *)
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: *)
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @param     p_PortManagementInfoContainer (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT)
   */
  function f_Check_NG_PDUSessionModificationComplete( NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                                 template (present) O1_Type p_PDU_SessionId,
                                                 template (present) ProcedureTransactionIdentifier p_PTI := ?,
                                                 template ExtdProtocolConfigOptions p_ExtdPCO := *,
                                                 template NG_PDU_SessionId p_OldPDU_SessionId  := *,
                                                 template NG_Request_Type p_RequestType  := *,
                                                 template S_NSSAI_Type p_S_NSSAI  := *,
                                                 template DNN p_DNN  := *,
                                                 template AdditionalInformation p_AdditionalInfo  := *,
                                                 template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                                 template ReleaseAssistanceInd p_ReleaseAssistanceInd := *,
                                                 template PortManagementInfoContainer p_PortManagementInfoContainer := *) return boolean
  {
    var boolean v_Result := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    
    // Check NAS Transport msg first
    v_Result := f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_PDU_SessionId,
                                           p_OldPDU_SessionId,
                                           p_RequestType,
                                           p_S_NSSAI,
                                           p_DNN,
                                           p_AdditionalInfo,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd);
    if (not v_Result) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_PDU_SESSION_MODIFICATION_COMPLETE (cr_NG_PDU_SessionId(-, p_PDU_SessionId), // @sic R5s200564 sic@
                                                                         p_PTI,
                                                                         p_ExtdPCO,
                                                                         p_PortManagementInfoContainer))) {  // @sic R5s201387 Baseline Moving sic@
      v_Result := true;
    } else {  // @sic R5s190944 sic@
      v_Result := false;
    }
    return v_Result;
  }
  
  /*
   * @desc      build the PDU SESSION ESTABLISHMENT REJECT COMMAND, Piggybacked into the DL NAS Transport
   * @param     p_PDU_SessionId
   * @param     p_PTI
   * @param     p_Cause             (default value: cs_GMM_GSM_Cause (omit, '00011010'B)
   * @param     p_BackOff           (default value: omit)
   * @param     p_SSC_Mode          (default value: omit)
   * @param     p_EAP               (default value: omit)
   * @param     p_ExtdPCO           (default value: omit)
   * @param     p_ReAttemptIndicator           (default value: omit)
   * @param     p_NGSM_CongestionReattemptInd           (default value: omit)
   * @param     p_ServiceLvlAA           (default value: omit)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (NR5GC)
   */
  function f_Get_NG_PDUSessionEstablishmentReject(template (value) O1_Type p_PDU_SessionId,
                                             template (value) ProcedureTransactionIdentifier p_PTI,
                                             template (value) GMM_GSM_Cause p_Cause := cs_GMM_GSM_Cause (omit, '00011010'B),
                                             template (omit) GPRS_Timer3 p_BackOff := omit,
                                             template (omit) AllowedSSCMode p_SSC_Mode := omit,
                                             template (omit) EAP_Message p_EAP := omit,
                                             template (omit) ExtdProtocolConfigOptions p_ExtdPCO := omit,
                                             template (omit) ReAttemptIndicator p_ReAttemptIndicator := omit,
                                             template (omit) NGSM_CongestionReattemptInd p_NGSM_CongestionReattemptInd := omit,
                                             template (omit) ServiceLvlAAContainer p_ServiceLvlAA := omit) return template (value) NG_NAS_DL_Pdu_Type
  {
    // @sic R5-198184 sic@
    var template (value) NG_NAS_DL_Message_Type v_GSMMsg;
    v_GSMMsg := cs_NG_PDU_SESSION_ESTABLISHMENT_REJECT (cs_NG_PDU_SessionId (p_PDU_SessionId, omit),
                                                   p_PTI,
                                                   p_Cause,
                                                   p_BackOff,
                                                   p_SSC_Mode,
                                                   p_EAP,
                                                   p_ExtdPCO,
                                                   p_ReAttemptIndicator,
                                                   p_NGSM_CongestionReattemptInd,   // @sic R5s201387 Baseline Moving sic@
                                                   p_ServiceLvlAA);               // @sic R5s221179 Baseline Moving sic@
    return f_Get_NG_DLNASTransport (cs_PayloadContainerType(tsc_PayloadContainerESMMsg),
                                    v_GSMMsg,
                                    -,
                                    p_PDU_SessionId,
                                    omit,
                                    omit,
                                    p_BackOff);
  }

  /*
   * @desc      Check the GSM STATUS, Piggybacked into the UL NAS Transport
   * @param     p_ReceivedMsgs
   * @param     p_PDU_SessionId
   * @param     p_PTI               (default value: ?)
   * @param     p_Cause
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: *)
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @return    boolean
   * @status    APPROVED (NR5GC)
   */
  function f_Check_NG_GSMStatus(NG_NAS_UL_Pdu_Type p_ReceivedMsgs,
                                template (present) O1_Type p_PDU_SessionId,
                                template (present) ProcedureTransactionIdentifier p_PTI := ?,
                                template (present) GMM_GSM_Cause p_Cause,
                                template NG_PDU_SessionId p_OldPDU_SessionId  := *,
                                template NG_Request_Type p_RequestType  := *,
                                template S_NSSAI_Type p_S_NSSAI  := *,
                                template DNN p_DNN  := *,
                                template AdditionalInformation p_AdditionalInfo  := *,
                                template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                template ReleaseAssistanceInd p_ReleaseAssistanceInd := *) return boolean
  {
    var boolean v_Result := false;
    var NG_NAS_UL_Message_Type v_GSMMsg := p_ReceivedMsgs.PiggybackedPduList[0].Msg;
    
    // Check NAS Transport msg first
    v_Result := f_Check_NG_ULNASTransport (p_ReceivedMsgs.Msg,
                                           cr_PayloadContainerType(tsc_PayloadContainerESMMsg), // @sic R5w190208 sic@
                                           p_PDU_SessionId,
                                           p_OldPDU_SessionId,
                                           p_RequestType,
                                           p_S_NSSAI,
                                           p_DNN,
                                           p_AdditionalInfo,
                                           p_MA_PDUSessionInfo,   // @sic R5s201387 Baseline Moving sic@
                                           p_ReleaseAssistanceInd);
    if (not v_Result) {
      return v_Result;
    } else if (match (v_GSMMsg, cr_NG_GSM_STATUS (cr_NG_PDU_SessionId(-, p_PDU_SessionId), // @sic R5s200564 sic@
                                                  p_PTI,
                                                  p_Cause))) {
      v_Result := true;
    } else {  // @sic R5s190944 sic@
      v_Result := false;
    }
    return v_Result;
  }

 /*
   * @desc      check the UL NAS TRANSPORT
   * @param     p_NASTransport
   * @param     p_PayloadContainerType
   * @param     p_PDU_SessionId     (default value: *)
   * @param     p_OldPDU_SessionId  (default value: *)
   * @param     p_RequestType       (default value: *)
   * @param     p_S_NSSAI           (default value: *)
   * @param     p_DNN               (default value: *)
   * @param     p_AdditionalInfo    (default value: *)
   * @param     p_MA_PDUSessionInfo (default value: *)
   * @param     p_ReleaseAssistanceInd (default value: *)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Check_NG_ULNASTransport(NG_NAS_UL_Message_Type p_NASTransport,
                                   template (present) PayloadContainerType p_PayloadContainerType,
                                   template O1_Type p_PDU_SessionId := *,
                                   template NG_PDU_SessionId p_OldPDU_SessionId := *,
                                   template NG_Request_Type p_RequestType := *,
                                   template S_NSSAI_Type p_S_NSSAI := *,
                                   template DNN p_DNN := *,
                                   template AdditionalInformation p_AdditionalInfo := *,
                                   template MA_PDUSessionInfo p_MA_PDUSessionInfo := *,      // @sic R5s201387 Baseline Moving sic@
                                   template ReleaseAssistanceInd p_ReleaseAssistanceInd := *) return boolean
  {
    var template NG_PDU_SessionId v_PDU_SessionId := omit;
    if (match(tsc_PayloadContainerESMMsg, p_PayloadContainerType.container) or match(tsc_PayloadContainerCIoTUserData, p_PayloadContainerType.container)) { // @sic R5s201387 Baseline Moving sic@
      if(ispresent(p_PDU_SessionId)) { // @sic R5s190626, R5s200564 sic@
        v_PDU_SessionId := cr_NG_PDU_SessionId ('12'O, p_PDU_SessionId);       // @sic R5s200564 sic@
      }
    }

    return match(p_NASTransport, cr_NG_UL_NAS_TRANSPORT(p_PayloadContainerType,
                                                        v_PDU_SessionId,
                                                        p_OldPDU_SessionId,
                                                        p_RequestType,
                                                        p_S_NSSAI,
                                                        p_DNN,
                                                        p_AdditionalInfo,
                                                        p_MA_PDUSessionInfo,        // @sic R5s201387 Baseline Moving sic@
                                                        p_ReleaseAssistanceInd));
  }

  /*
   * @desc      build the DL NAS TRANSPORT
   * @param     p_PayloadContainerType
   * @param     p_PiggyBackedGSMMsg
   * @param     p_Payload           (default value: cs_DummyPayloadContainer)
   * @param     p_PDU_SessionId     (default value: omit)
   * @param     p_AdditionalInfo    (default value: omit)
   * @param     p_Cause             (default value: omit)
   * @param     p_BackOff           (default value: omit)
   * @param     p_LowerBoundTimerValue   (default value: omit)
   * @return    template (value) NG_NAS_DL_Pdu_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_Get_NG_DLNASTransport(template (value) PayloadContainerType p_PayloadContainerType,
                                   template (omit) NG_NAS_DL_Message_Type p_PiggyBackedGSMMsg,
                                   template (value) PayloadContainer p_Payload := cs_DummyPayloadContainer, // dummy value for p_PiggyBackedGSMMsg is encoded in emulator
                                   template (omit) O1_Type p_PDU_SessionId := omit,
                                   template (omit) AdditionalInformation p_AdditionalInfo := omit,
                                   template (omit) GMM_GSM_Cause p_Cause := omit,
                                   template (omit) GPRS_Timer3 p_BackOff := omit,
                                   template (omit) GPRS_Timer3 p_LowerBoundTimerValue := omit) return template (value) NG_NAS_DL_Pdu_Type
  {
    var template (omit) NG_PDU_SessionId v_PDU_SessionId := omit;
    var template (value) NG_NAS_DL_Message_Type v_GMMMsg;
    
    if (match(tsc_PayloadContainerESMMsg, p_PayloadContainerType.container) and isvalue(p_PDU_SessionId)) { // @sic R5s190626 sic@
      v_PDU_SessionId := cs_NG_PDU_SessionId(p_PDU_SessionId);
    }
    
    v_GMMMsg := cs_NG_DL_NAS_TRANSPORT (p_PayloadContainerType,
                                        p_Payload,
                                        v_PDU_SessionId,
                                        p_AdditionalInfo,
                                        p_Cause,
                                        p_BackOff,
                                        p_LowerBoundTimerValue);   // @sic R5s221179 Baseline Moving sic@
    if (isvalue(p_PiggyBackedGSMMsg)) { // @sic R5s210234 sic@
      return cs_NG_NAS_DL_PduWithPiggybacking (v_GMMMsg, p_PiggyBackedGSMMsg);
    } else {
      return cs_NG_NAS_DL_PduWithoutPiggyback (v_GMMMsg);
    }
  }
  
  /*
   * @desc      build the NSSAI_DELETE_REQUEST test mode message
   * @param     p_DeleteType
   * @param     p_PLMN              (default value: omit)
   * @param     p_AccessType        (default value: omit)
   * @return    template (value) NG_NAS_DL_Message_Type
   * @status    APPROVED (NR5GC)
   */
  function f_Get_NSSAI_DELETE_REQUEST(DeleteNSSAI_Type p_DeleteType,
                                      template (omit) NAS_PlmnId p_PLMN := omit,
                                      template (omit) B2_Type p_AccessType := omit) return template (value) NG_NAS_DL_Message_Type
  {
    var template (omit) NAS_PlmnId v_PLMN := omit; // compiler warning may be ignored due to check
    var B2_Type v_AccessType := '10'B; // must set to a valid value, so assume for both if not specified
    var template (omit) AllowedNSSAI v_AllowedNSSAI := omit;
    var B8_Type v_DeleteNSSAIType;
    
    select (p_DeleteType) {
      case (Delete_Default_Configured) {
        v_DeleteNSSAIType := tsc_DeleteNSSAI_DefaultConfiguredNSSAI;
      }
      case (Delete_Configured) {
        v_DeleteNSSAIType := tsc_DeleteNSSAI_ConfiguredNSSAI;
        if (isvalue(p_PLMN)){
          v_PLMN := p_PLMN;
        } else {
          v_PLMN := '000000'O
        }
      }
      case (Delete_Allowed) {
        v_DeleteNSSAIType := tsc_DeleteNSSAI_AllowedNSSAI;
        if (isvalue(p_PLMN)){
          v_PLMN := p_PLMN;
        } else {
          v_PLMN := '000000'O
        }
        if (isvalue(p_AccessType)) {
          v_AccessType := valueof(p_AccessType);
        }
        v_AllowedNSSAI := cs_AllowedNSSAI (v_PLMN, v_AccessType); // compiler warning may be ignored due to check
      }
    }
    return cs_NSSAI_DELETE_REQUEST (v_DeleteNSSAIType,
                                    v_PLMN,
                                    v_AllowedNSSAI);
  }

  // ===========================================================================

  /*
   * @desc      NR5GC GetPdnIndex
   * @param     p_GSM_MobilityInfo
   * @return    PDN_Index_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
   function f_NR5GC_GetPdnIndex(GSM_MobilityInfo_Type p_GSM_MobilityInfo) return PDN_Index_Type
  {
    // @sic R5-200256, R5-202550, R5-206296 sic@
    // Make sure the PDN is the same in both EUTRA and NR @sic R5s210149 sic@
    return f_GetMultiPdnIndex(p_GSM_MobilityInfo.PDUType);
  }

 //----------------------------------------------------------------------------
 /*
   * @desc      PDN Address TS 24.501 clause 9.11.4.10
   *            Default value according to TS 36.508 table 6.6.1-1 (which requires a 'static' value) and table 4.7.3-6
   *            Based on f_EUTRA_NB_GetPDNAddress
   * @param     p_IPv4AllocationViaNas
   * @param     p_PDN_TypeToBeUsed
   * @param     p_PDN_Address
   * @return    PDU_Address
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_NG_GetPDNAddress(boolean p_IPv4AllocationViaNas,
                              B3_Type p_PDN_TypeToBeUsed,
                              PDN_AddressInfo_Type p_PDN_Address) return PDU_Address
  {
    var O4_Type v_Addr4 := f_Convert_IPv4Addr2OctString(p_PDN_Address.UE_IPAddressIPv4); // @sic R5s200643 sic@
    var octetstring v_Addr6:= f_Convert_IPv6Addr2OctString(p_PDN_Address.UE_IPAddressIPv6); // @sic R5s200643 sic@
    var Type4Length_Type v_IeLength;
    var octetstring v_AddressInfo;
    var PDU_Address v_PDU_Address;
    
    // set IP addresses
    v_Addr6 := substr(v_Addr6, 8, 8);  // Use only the IPv6 interface identifier, which are the 8 least significant octets of theIPv6 address

    if (not p_IPv4AllocationViaNas) {       // => IPv4 address via DHCP signalling (if IPv4)
      v_Addr4 := '00000000'O;
    }

    // set IE
    select (p_PDN_TypeToBeUsed) {
      case (tsc_PdnType_IPv4) {
        if (not pc_IPv4) {
          FatalError(__FILE__, __LINE__, "IPv4 selected but is not supported");
        }
        v_IeLength := '05'O;
        v_AddressInfo := v_Addr4;
      }
      case (tsc_PdnType_IPv6) {
        if (not pc_IPv6) {
          FatalError(__FILE__, __LINE__, "IPv6 selected but is not supported");
        }
        v_IeLength := '09'O;
        v_AddressInfo := v_Addr6;
      }
      case (tsc_PdnType_IPv4v6) {
        if (not pc_IPv4 or not pc_IPv6) {
          FatalError(__FILE__, __LINE__, "IPv4v6 selected but at least one is not supported");
        }
        v_IeLength := '0D'O;
        v_AddressInfo := v_Addr6 & v_Addr4;
      }
    }

    v_PDU_Address := {
      iei := '29'O,
      iel := v_IeLength,
      spare      := tsc_Spare4,  // @sic R5s201526 sic@
      si16LLA    := '0'B,        // @sic R5s201526 sic@
      typeValue  := p_PDN_TypeToBeUsed,
      adressInfo := v_AddressInfo,
      ipv6Address := omit  // @sic R5s210267 sic@
    };

    return v_PDU_Address;
  }

  /*
   * @desc      Checks DNN to see if it requests IMS,  based on f_EUTRA_GetAPNForIMS
   * @param     p_DNNFromReq
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT)
   */
   /*
  function f_NG_IsDNNForIMS(DNN p_DNNFromReq) return boolean
  {
    return match(IMS_DNN, f_GetPDNTypeFromDNN (p_DNNFromReq));
  }
*/
  /*
   * @desc      Returns the DNN Name to be used in Accept message
   *            returns "IMS" and the operator id "mnc<MNC>.mcc<MCC>.gprs"
   * @param     p_PLMN
   * @return    octetstring
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_NG_GetDNNForIMS(NAS_PlmnId p_PLMN) return octetstring
  { // @sic R5s201327 sic@ : removed the test of the incoming DNN. Always return the IMS DNN
    var hexstring v_PLMN_hexstring := oct2hex(p_PLMN);
    var charstring v_MNC := "";
    var charstring v_MCC := "";
    var octetstring v_OperatorId;
    var CharStringList_Type v_LabelList;
    
    v_MCC := int2str(hex2int(v_PLMN_hexstring[1])) & int2str(hex2int(v_PLMN_hexstring[0])) & int2str(hex2int(v_PLMN_hexstring[3]));
    v_MNC := int2str(hex2int(v_PLMN_hexstring[5])) & int2str(hex2int(v_PLMN_hexstring[4]));
    if (v_PLMN_hexstring[2] != 'F'H) {
    v_MNC := v_MNC & int2str(hex2int(v_PLMN_hexstring[2]));
    }

    v_LabelList := {f_APN_MccMncLabel("mnc", v_MNC), f_APN_MccMncLabel("mcc", v_MCC), "gprs" };
    v_OperatorId := f_DomainName_EncodeLabels(v_LabelList);

    return f_DomainName_EncodeLabels({"IMS"}) & v_OperatorId;
  }

  //----------------------------------------------------------------------------
  type record of PDN_AddressInfo_Type ListOfPDN_AddressInfo_Type;   /* @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */

  /*
   * @desc      Function used to check whether the UE requests a P-CSCF address in its PCO
   *            If the UE does not support IMS, or doesn't request a P-CSCF address, the function returns omit
   * @param     p_ConfigOptionsRX
   * @param     p_PDN_AddressInfo
   * @return    template (omit) NAS_ExtdProtocolConfigOptions_Type
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_NG_NAS_GetExtdProtocolConfigOptionList(NAS_ExtdProtocolConfigOptions_Type p_ConfigOptionsRX,
                                                    ListOfPDN_AddressInfo_Type p_PDN_AddressInfo) return template (omit) NAS_ExtdProtocolConfigOptions_Type
  {
    var template (omit) NAS_ExtdProtocolConfigOptions_Type v_ProtocolContainerList := omit;
    var integer v_PcoCnt := 0;
    var O2_Type v_ProtocolId;
    var octetstring v_Contents;
    var integer i;
    var integer j;
    
    for (j := 0; j < lengthof(p_PDN_AddressInfo); j := j + 1) {   // @sic R5-213400 sic@
      for (i := 0; i < lengthof(p_ConfigOptionsRX); i := i + 1) {
      
        v_ProtocolId := p_ConfigOptionsRX[i].protocolID;
        v_Contents := ''O;
      
        select (v_ProtocolId) {  // See 24.008 Table 10.5.154
          case ('0001'O) {       // P-CSCF IPv6 address
            v_Contents := f_Convert_IPv6Addr2OctString(p_PDN_AddressInfo[j].PCSCF_IPAddressIPv6); // @sic R5s200643 sic@
          }
          case ('000C'O) {       // P-CSCF IPv4 address
            v_Contents := f_Convert_IPv4Addr2OctString(p_PDN_AddressInfo[j].PCSCF_IPAddressIPv4); // @sic R5s200643 sic@
          }
          case ('0003'O) {       // DNS Server IPv6 address  @sic R5-224166 sic@
            if (f_GetTestcaseAttrib_XCAP(testcasename())) { // @sic R5-231185 sic@
              v_Contents := f_Convert_IPv6Addr2OctString(p_PDN_AddressInfo[j].DNS_ServerAddressIPv6);
            }
          }
          case ('000D'O) {       // DNS Server IPv4 address  @sic R5-224166 sic@
            if (f_GetTestcaseAttrib_XCAP(testcasename())) { // @sic R5-231185 sic@
              v_Contents := f_Convert_IPv4Addr2OctString(p_PDN_AddressInfo[j].DNS_ServerAddressIPv4);
            }
          }
        }
      
        if (lengthof(v_Contents) > 0) {
          v_ProtocolContainerList[v_PcoCnt] := cs_ProtocolContainer(v_ProtocolId, v_Contents);
          v_PcoCnt := v_PcoCnt + 1;
        }
      }
    }
    return v_ProtocolContainerList;
  }

  /*
   * @desc      check PS Data Off is deactivated if included in the given list, or omit otherwise
   * @param     p_Pco
   * @param     p_Status            (default value: '01'O)
   * @return    boolean
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_ExtdProtocolConfigOptions_CheckPSDataOff(template (omit) ExtdProtocolConfigOptions p_Pco,
                                                       O1_Type p_Status:='01'O) return boolean
  {
    var template (omit) octetstring v_Content := f_ExtdProtocolConfigOptions_Get(p_Pco, '0017'O);
    var boolean v_Result := false;
    
    if (isvalue(v_Content)) {
      if (lengthof(v_Content) > 0) {
        v_Result := match (p_Status, v_Content); //@sic R5s220424 R5s220828 sic@
      }
    }
    return v_Result;
  }

  //----------------------------------------------------------------------------
  /*
   * @desc      wrapper for f_NG_NAS_GetExtdProtocolConfigOptionList
   * @param     p_Pco
   * @param     p_PDN_AddressInfo
   * @return    template (omit) ExtdProtocolConfigOptions
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_NG_GetDefaultExtdProtocolConfigOptions(template (omit) ExtdProtocolConfigOptions p_Pco,
                                             ListOfPDN_AddressInfo_Type p_PDN_AddressInfo) return template (omit) ExtdProtocolConfigOptions
  {
    var template (omit) NAS_ExtdProtocolConfigOptions_Type v_ProtocolContainerList := omit;
    var ExtdProtocolConfigOptions v_ProtocolConfigOptionsRX;
    
    if (isvalue(p_Pco)) {
      v_ProtocolConfigOptionsRX := valueof(p_Pco);
      if (ispresent(p_Pco.pco)) {
        v_ProtocolContainerList := f_NG_NAS_GetExtdProtocolConfigOptionList(v_ProtocolConfigOptionsRX.pco, p_PDN_AddressInfo); // @sic R5s200643 sic@
      }
    }
    
    return f_NG_NAS_ExtdProtocolConfigOptionsTX(v_ProtocolContainerList);
  }
  
  /*
   * @desc      Common function to build up ProtocolConfigOptions
   * @param     p_ProtocolContainers
   * @return    template (omit) ExtdProtocolConfigOptions
   * @status    APPROVED (IMS, NR5GC, NR5GC_IRAT, POS)
   */
  function f_NG_NAS_ExtdProtocolConfigOptionsTX(template (omit) NAS_ExtdProtocolConfigOptions_Type  p_ProtocolContainers) return template (omit) ExtdProtocolConfigOptions
  {
    if (isvalue(p_ProtocolContainers)) {
      
      return f_NAS_ExtdProtocolConfigOptionsTX (p_ProtocolContainers); // @sic R5s200643 sic@
    } else {
      return omit;
    }
  }
  
   /*
   * @desc      To calculate the Bit Rate for 5G QoSFlow for the UT command
   * @param     p_Unit - 1st octet of Qos Parameter
   * @param     p_Value - 2nd & 3rd octets of Qos Parameter
   * @return    integer
   * @status    APPROVED (NR5GC)
   */
  function fl_Calculate5G_BitRate(integer p_Unit, integer p_Value) return integer
  {
    var integer v_BitRate := p_Value;
    var integer v_Exponent := 0;
    
    if (p_Unit > 0) { // Do nothing if 0
        v_Exponent := ((p_Unit-1) mod 5); // multiply by either 1, 4, 16, 64 or 256
        if (v_Exponent > 0) {
          v_BitRate := v_BitRate * f_Power(4, v_Exponent);
        }
        v_Exponent := (((p_Unit-1) / 5) * 3); // multiply by multiples of 1000
        if (v_Exponent > 0) {
          v_BitRate := v_BitRate * f_Power(10, v_Exponent);
        }
    }
    return v_BitRate;
  }
  
  /*
   * @desc      To convert a 5G QoSFlow into a charstring for the UT command
   * @param     p_QoSFlow
   * @return    charstring
   * @status    APPROVED (NR5GC)
   */
  function f_Convert5G_QoSFlow_ForATCommand(template (value) QoS_Flow p_QoSFlow) return charstring
  {
    var QoS_Flow v_QoSFlow := valueof(p_QoSFlow);
    var charstring v_QoSstring := "";
    var integer i;
    var O1_Type v_Identifier;
    var octetstring v_Contents;
    var integer v_QI5 := 0;
    var integer v_Unit := 0;
    var integer v_DL_GFBR := 0;
    var integer v_UL_GFBR := 0;
    var integer v_DL_MFBR := 0;
    var integer v_UL_MFBR := 0;
    
    for (i := 0; i < bit2int(v_QoSFlow.numOfParameters); i := i+1){
      v_Identifier := v_QoSFlow.parameterList[i].id;            // @sic R5s190673 sic@
      v_Contents := v_QoSFlow.parameterList[i].qosParam;
      select (v_Identifier) { // check the 1st octet of each parameter
        case ('01'O){
          v_QI5 := oct2int(v_Contents);
        }
        case ('03'O){
          v_Unit := oct2int(substr(v_Contents, 0, 1));
          v_DL_GFBR := oct2int(substr(v_Contents, 1, 2));
          v_DL_GFBR := fl_Calculate5G_BitRate(v_Unit, v_DL_GFBR);
        }
        case ('02'O){
          v_Unit := oct2int(substr(v_Contents, 0, 1));
          v_UL_GFBR := oct2int(substr(v_Contents, 1, 2));
          v_UL_GFBR := fl_Calculate5G_BitRate(v_Unit, v_UL_GFBR);
        }
        case ('05'O){
          v_Unit := oct2int(substr(v_Contents, 0, 1));
          v_DL_MFBR := oct2int(substr(v_Contents, 1, 2));
          v_DL_MFBR := fl_Calculate5G_BitRate(v_Unit, v_DL_MFBR);
        }
        case ('04'O){
          v_Unit := oct2int(substr(v_Contents, 0, 1));
          v_UL_MFBR := oct2int(substr(v_Contents, 1, 2));
          v_UL_MFBR := fl_Calculate5G_BitRate(v_Unit, v_UL_MFBR);
        }
      }
    }
    if (v_QI5 != 0) {
      v_QoSstring := v_QoSstring & int2str(v_QI5);
    } else {
      FatalError(__FILE__, __LINE__, "There must be a 5QI in the QosFlow");
    }
    if (v_DL_GFBR != 0) {
      v_QoSstring := v_QoSstring &","& int2str(v_DL_GFBR);
    }
    if (v_UL_GFBR != 0) {
      v_QoSstring := v_QoSstring &","& int2str(v_UL_GFBR);
    }
    if (v_DL_MFBR != 0) {
      v_QoSstring := v_QoSstring &","& int2str(v_DL_MFBR);
    }
    if (v_UL_MFBR != 0) {
      v_QoSstring := v_QoSstring &","& int2str(v_UL_MFBR);
    }
    return v_QoSstring;
  }

  /*
   * @desc      to convert the PDU_SessionStatus into an integer list of transferred session ids
   * @param     p_SessionStatus
   * @return    IntegerList_Type
   * @status    APPROVED (NR5GC_IRAT)
   */
  function f_NG_ConvertPDU_SessionStatus (PDU_SessionStatus p_SessionStatus) return IntegerList_Type
  {
    var IntegerList_Type v_List := {};
    var integer v_ListPosition := 0;
    var integer v_TypePosition;
    var integer v_SessionId;
    
    // check ids 7 - 0
    v_SessionId := 7;
    for (v_TypePosition := 0; v_TypePosition < 8; v_TypePosition := v_TypePosition + 1) {
      if (p_SessionStatus.psi0_7[v_TypePosition] == '1'B) {
        v_List[v_ListPosition] := v_SessionId;
        v_ListPosition := v_ListPosition + 1;
      }
      v_SessionId := v_SessionId - 1;
    }
    
    // check ids 15 to 8
    v_SessionId := 15;
    for (v_TypePosition := 0; v_TypePosition < 8; v_TypePosition := v_TypePosition + 1) {
      if (p_SessionStatus.psi8_15[v_TypePosition] == '1'B) {
        v_List[v_ListPosition] := v_SessionId;
        v_ListPosition := v_ListPosition + 1;
      }
      v_SessionId := v_SessionId - 1;
    }
    
    return v_List;
  }

 
}
