/******************************************************************************/ // @copyright Copyright Notification // No part may be reproduced except as authorized by written permission. // The copyright and the foregoing restriction extend to reproduction in all media. // (c) 2023, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). // All rights reserved. // @version: IWD_23wk37 // $Date: 2022-11-29 17:53:31 +0100 (Tue, 29 Nov 2022) $ // $Rev: 34751 $ /******************************************************************************/ module NAS_AuxiliaryDefsAndFunctions { import from CommonDefs all; import from Parameters all; import from NAS_CommonTypeDefs all; import from NAS_CommonTemplates all; import from CommonIP all; template (value) ExtdEmergNum cs_ExtdEmergNum (octetstring p_Digits, octetstring p_SubServices := ''O) := { /* @status APPROVED (NR5GC) */ len := int2oct(lengthof(p_Digits), 1), digits := p_Digits, // BCD numbers lengthOfSubService := int2oct(lengthof(p_SubServices), 1), subServices := p_SubServices }; //============================================================================ // Protocol Configuration Options (PCO) //---------------------------------------------------------------------------- /* * @desc Function used to check whether the UE requests in its PCO an address allocation via NAS signalling * If the UE does not send PCO, then address assignment shall be via DHCP. TS 36.508 table 4.7.3-6. * @param p_Pco * @return boolean * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_CheckPCOforIPallocationViaNas(template (omit) ProtocolConfigOptions p_Pco) return boolean { var NAS_ProtocolConfigOptions_Type v_ProtocolContainerList; var integer i; if (isvalue(p_Pco.pco)) { /* @sic R5s170030 change 8 sic@ */ v_ProtocolContainerList := valueof (p_Pco.pco); for (i := 0; i < lengthof(v_ProtocolContainerList); i := i + 1) { if (v_ProtocolContainerList[i].protocolID == '000B'O) { // TS 24.008 clause 10.5.6.3 // @sic R5s090322 sic@ return false; // @sic R5s090322 sic@ } } } return true; // @sic R5s090322 sic@ } //---------------------------------------------------------------------------- /* * @desc Function used to check whether the UE requests in its PCO an address allocation via NAS signalling * If the UE does not send PCO, then address assignment shall be via DHCP. TS 36.508 table 4.7.3-6. * @param p_Pco * @return boolean * @status APPROVED (ENDC, IMS, NBIOT, NR5GC, NR5GC_IRAT, POS) */ function f_CheckExtdPCOforIPallocationViaNas(template (omit) ExtdProtocolConfigOptions p_Pco) return boolean { var ExtdProtocolConfigOptions v_Pco; var integer i; if (isvalue(p_Pco)) { v_Pco := valueof (p_Pco); if (ispresent(v_Pco.pco)) { // @sic R5s170233 sic@ for (i := 0; i < lengthof(v_Pco.pco); i := i + 1 ) { if(v_Pco.pco[i].protocolID == '000B'O) { // TS 24.008 clause 10.5.6.3 return false; } } } } return true; } //------------------------------------ /* * @desc return * omit when there is no protocol config option with the given id in the given list * content of the protocol config option (which can be empty or omit) otherwise * @param p_Pco * @param p_ProtocolID * @return template (omit) octetstring * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_ProtocolConfigOptions_Get(template (omit) ProtocolConfigOptions p_Pco, O2_Type p_ProtocolID) return template (omit) octetstring { var NAS_ProtocolConfigOptions_Type v_ProtocolConfigOptions; var integer i; if (isvalue(p_Pco.pco)) { v_ProtocolConfigOptions := valueof(p_Pco.pco); for (i := 0; i < lengthof(v_ProtocolConfigOptions); i := i + 1) { if (v_ProtocolConfigOptions[i].protocolID == p_ProtocolID) { // TS 24.008 clause 10.5.6.3 return v_ProtocolConfigOptions[i].content; } } } return omit; } /* * @desc return * omit when there is no protocol config option with the given id in the given list * content of the protocol config option (which can be empty or omit) otherwise * @param p_Pco * @param p_ProtocolID * @return template (omit) octetstring * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC, NR5GC_IRAT, POS) */ function f_ExtdProtocolConfigOptions_Get(template (omit) ExtdProtocolConfigOptions p_Pco, O2_Type p_ProtocolID) return template (omit) octetstring { var NAS_ExtdProtocolConfigOptions_Type v_ProtocolConfigOptions; var integer i; if (isvalue(p_Pco.pco)) { v_ProtocolConfigOptions := valueof(p_Pco.pco); for (i := 0; i < lengthof(v_ProtocolConfigOptions); i := i + 1) { if (v_ProtocolConfigOptions[i].protocolID == p_ProtocolID) { // TS 24.008 clause 10.5.6.3 return v_ProtocolConfigOptions[i].content; } } } return omit; } /* * @desc return SessionId if included in the given list or omit otherwise * @param p_Pco * @return template (omit) integer * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_ProtocolConfigOptions_GetSessionId(template (omit) ProtocolConfigOptions p_Pco) return template (omit) integer { var template (omit) octetstring v_Content := f_ProtocolConfigOptions_Get(p_Pco, '001A'O); var octetstring v_Octetstring; if (isvalue(v_Content)) { v_Octetstring := valueof(v_Content); if (lengthof(v_Octetstring) > 0) { return oct2int(v_Octetstring); } } return omit; } /* * @desc return QosFlowId if included in the given list or omit otherwise * @param p_Pco * @return template (omit) integer * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_ProtocolConfigOptions_GetQosFlowId(template (omit) ProtocolConfigOptions p_Pco) return template (omit) integer { var template (omit) octetstring v_Content := f_ProtocolConfigOptions_Get(p_Pco, '001F'O); var octetstring v_Octetstring; if (isvalue(v_Content)) { v_Octetstring := valueof(v_Content); if (lengthof(v_Octetstring) > 0) { return (oct2int(v_Octetstring[0]) mod 64); // QFI of the 1st QoS flow is in the lower 6 bits of the 1st octet } } return omit; } /* * @desc return SessionId if included in the given list or omit otherwise * @param p_Pco * @return template (omit) integer * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_ExtdProtocolConfigOptions_GetSessionId(template (omit) ExtdProtocolConfigOptions p_Pco) return template (omit) integer { var template (omit) octetstring v_Content := f_ExtdProtocolConfigOptions_Get(p_Pco, '001A'O); var octetstring v_Octetstring; if (isvalue(v_Content)) { v_Octetstring := valueof(v_Content); if (lengthof(v_Octetstring) > 0) { return oct2int(v_Octetstring); } } return omit; } /* * @desc return QosFlowId if included in the given list or omit otherwise * @param p_Pco * @return template (omit) integer * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_ExtdProtocolConfigOptions_GetQosFlowId(template (omit) ExtdProtocolConfigOptions p_Pco) return template (omit) integer { var template (omit) octetstring v_Content := f_ExtdProtocolConfigOptions_Get(p_Pco, '001F'O); var octetstring v_Octetstring; if (isvalue(v_Content)) { v_Octetstring := valueof(v_Content); if (lengthof(v_Octetstring) > 0) { return (oct2int(v_Octetstring[0]) mod 64); // QFI of the 1st QoS flow is in the lower 6 bits of the 1st octet } } return omit; } //------------------------------------ /* * @desc Function used to check whether the UE requests in its PCO a specific protocol * (SIP signalling) * @param p_Pco * @param p_ProtocolID * @return boolean * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, POS) */ function f_CheckPCOforProtocolID(template (omit) ProtocolConfigOptions p_Pco, O2_Type p_ProtocolID) return boolean { var ProtocolConfigOptions v_Pco; var integer i; if (isvalue(p_Pco)) { v_Pco := valueof (p_Pco); for (i := 0; i < lengthof(v_Pco.pco); i := i + 1) { if(v_Pco.pco[i].protocolID == p_ProtocolID) { // TS 24.008 clause 10.5.6.3 return true; } } } return false; } /* * @desc Function used to check whether the UE requests in its PCO a specific protocol * (SIP signalling) * @param p_Pco * @param p_ProtocolID * @return boolean * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, POS) */ function f_CheckExtdPCOforProtocolID(template ExtdProtocolConfigOptions p_Pco, O2_Type p_ProtocolID) return boolean { var ExtdProtocolConfigOptions v_Pco; var integer i; if (isvalue(p_Pco)) { v_Pco := valueof (p_Pco); for (i := 0; i < lengthof(v_Pco.pco); i := i + 1) { if(v_Pco.pco[i].protocolID == p_ProtocolID) { // TS 24.008 clause 10.5.6.3 return true; } } } return false; } //------------------------------------ /* * @desc Function used to check whether the UE requests a P-CSCF address or DNS server address in its PCO * If the UE does not support IMS, or doesn't request a P-CSCF address, the function returns the default PCO, PPP * @param p_ConfigOptionsRX * @param p_PdnIndex (default value: PDN_1) * @param p_AdditionalProtocolConfigOptions (default value: {}) * @param p_IgnoreIM_CN_SubsystemSignalingFlag (default value: true) * @return template (value) NAS_ProtocolConfigOptions_Type * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_NAS_GetProtocolConfigOptionList(NAS_ProtocolConfigOptions_Type p_ConfigOptionsRX, PDN_Index_Type p_PdnIndex := PDN_1, template (value) NAS_ProtocolConfigOptions_Type p_AdditionalProtocolConfigOptions := {}, boolean p_IgnoreIM_CN_SubsystemSignalingFlag := true) return template (value) NAS_ProtocolConfigOptions_Type { /* @sic R5-198996: p_AdditionalProtocolConfigOptions for 5GC options sic@ */ var PDN_AddressInfo_Type v_PDN_AddressInfo := f_PDN_AddressInfo_Get(p_PdnIndex); var template (value) NAS_ProtocolConfigOptions_Type v_ProtocolContainerList := {}; var integer v_PcoCnt := 0; var O2_Type v_ProtocolId; var octetstring v_Contents; var integer i; 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 if (pc_IMS) { v_Contents := f_Convert_IPv6Addr2OctString(v_PDN_AddressInfo.PCSCF_IPAddressIPv6); } } case ('0002'O) { // IM CN Subsystem Signalling Flag, reply with an empty container if (not p_IgnoreIM_CN_SubsystemSignalingFlag) { v_ProtocolContainerList[v_PcoCnt] := cs_ProtocolContainer_Common(v_ProtocolId); v_PcoCnt := v_PcoCnt + 1; continue; } } case ('0003'O) { // DNS Server IPv6 address v_Contents := f_Convert_IPv6Addr2OctString(v_PDN_AddressInfo.DNS_ServerAddressIPv6); } case ('000C'O) { // P-CSCF IPv4 address if (pc_IMS) { v_Contents := f_Convert_IPv4Addr2OctString(v_PDN_AddressInfo.PCSCF_IPAddressIPv4); } } case ('000D'O) { // DNS Server IPv4 address v_Contents := f_Convert_IPv4Addr2OctString(v_PDN_AddressInfo.DNS_ServerAddressIPv4); } } if (lengthof(v_Contents) > 0) { v_ProtocolContainerList[v_PcoCnt] := cs_ProtocolContainer(v_ProtocolId, v_Contents); v_PcoCnt := v_PcoCnt + 1; } } return valueof(v_ProtocolContainerList) & valueof(p_AdditionalProtocolConfigOptions); } /* * @desc wrapper for f_GetDefaultProtocolConfigOptionList * @param p_Pco * @param p_PdnIndex (default value: PDN_1) * @param p_AdditionalProtocolConfigOptions (default value: {}) * @return template (value) ProtocolConfigOptions * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_GetDefaultProtocolConfigOptions(template (omit) ProtocolConfigOptions p_Pco, PDN_Index_Type p_PdnIndex := PDN_1, template (value) NAS_ProtocolConfigOptions_Type p_AdditionalProtocolConfigOptions := {}) return template (value) ProtocolConfigOptions { /* @sic R5s130362 - MCC160 Implementation sic@ */ /* @sic R5s141127 change 4 - MCC160 Comments: split into f_GetDefaultProtocolConfigOptions and f_GetDefaultProtocolConfigOptionList sic@ */ /* @sic R5-198996: p_AdditionalProtocolConfigOptions for 5GC options sic@ */ var template (value) NAS_ProtocolConfigOptions_Type v_ProtocolContainerListTX := {}; var NAS_ProtocolConfigOptions_Type v_ProtocolContainerListRX; if (isvalue(p_Pco.pco)) { /* @sic R5s170030 change 8 sic@ */ v_ProtocolContainerListRX := valueof(p_Pco.pco); v_ProtocolContainerListTX := f_NAS_GetProtocolConfigOptionList(v_ProtocolContainerListRX, p_PdnIndex, p_AdditionalProtocolConfigOptions); } return f_NAS_ProtocolConfigOptionsTX(v_ProtocolContainerListTX); } //---------------------------------------------------------------------------- /* * @desc Common function to build up ProtocolConfigOptions * @param p_ProtocolContainers * @return template (value) ExtdProtocolConfigOptions * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NBIOT, NR5GC, NR5GC_IRAT, POS) */ function f_NAS_ExtdProtocolConfigOptionsTX(template (omit) NAS_ExtdProtocolConfigOptions_Type p_ProtocolContainers) return template (value) ExtdProtocolConfigOptions { var integer v_Length := 1; // there are at least ext, spare, configProtocol var integer i; if (isvalue(p_ProtocolContainers)) { // @sic R5s170233 sic@ for (i:=0; i < lengthof(p_ProtocolContainers); i:=i+1) { v_Length := v_Length + oct2int(valueof(p_ProtocolContainers[i].protocolLength)) + 3; // 2 octets for protocolID and 1 octet for protocolLength } } return cs_ExtdPCO(int2oct(v_Length, 2), p_ProtocolContainers); } /* * @desc wrapper for f_GetDefaultExtdProtocolConfigOptionList * @param p_Pco * @param p_PdnIndex (default value: PDN_1) * @return template (value) ExtdProtocolConfigOptions * @status APPROVED (NBIOT) */ function f_GetDefaultExtdProtocolConfigOptions(template (omit) ExtdProtocolConfigOptions p_Pco, PDN_Index_Type p_PdnIndex := PDN_1) return template (value) ExtdProtocolConfigOptions { var template (omit) NAS_ExtdProtocolConfigOptions_Type v_ProtocolContainerList := omit; // @sic R5s170233 sic@ var ExtdProtocolConfigOptions v_ProtocolConfigOptionsRX; if (isvalue(p_Pco)) { v_ProtocolConfigOptionsRX := valueof(p_Pco); if (ispresent(p_Pco.pco)) { // @sic R5s170233 sic@ v_ProtocolContainerList := f_NAS_GetExtdProtocolConfigOptionList(v_ProtocolConfigOptionsRX.pco, -, p_PdnIndex); // @sic R5-200649, R5s200643 sic@ } } return f_NAS_ExtdProtocolConfigOptionsTX(v_ProtocolContainerList); } /* * @desc Function used to check whether the UE requests a P-CSCF address or DNS server address in its PCO * If the UE does not support IMS, or doesn't request a P-CSCF address, the function returns the default PCO, PPP * @param p_ConfigOptionsRX * @param p_IgnoreIM_CN_SubsystemSignalingFlag (default value: true) * @param p_PdnIndex (default value: PDN_1) * @return template (omit) NAS_ExtdProtocolConfigOptions_Type * @status APPROVED (NBIOT) */ function f_NAS_GetExtdProtocolConfigOptionList(NAS_ExtdProtocolConfigOptions_Type p_ConfigOptionsRX, boolean p_IgnoreIM_CN_SubsystemSignalingFlag := true, PDN_Index_Type p_PdnIndex := PDN_1) return template (omit) NAS_ExtdProtocolConfigOptions_Type { /* @sic R5s170515 change 1: "template (omit)" for return type sic@ */ var PDN_AddressInfo_Type v_PDN_AddressInfo := f_PDN_AddressInfo_Get(p_PdnIndex); // @sic R5-200649 sic@ 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; 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 ('0002'O) { // IM CN Subsystem Signalling Flag, reply with an empty container if (not p_IgnoreIM_CN_SubsystemSignalingFlag) { v_ProtocolContainerList[v_PcoCnt] := cs_ProtocolContainer_Common(v_ProtocolId); v_PcoCnt := v_PcoCnt + 1; continue; } } case ('0003'O) { // DNS Server IPv6 address v_Contents := f_Convert_IPv6Addr2OctString(v_PDN_AddressInfo.DNS_ServerAddressIPv6); } case ('000D'O) { // DNS Server IPv4 address v_Contents := f_Convert_IPv4Addr2OctString(v_PDN_AddressInfo.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; // @sic R5-200649, R5s200643 sic@ } //---------------------------------------------------------------------------- /* * @desc Get Pdn Index to be used in Multi PDN/PDU ATS * @param p_DNNType * @return PDN_Index_Type * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ function f_GetMultiPdnIndex(PDU_PDN_DNN_Type p_DNNType) return PDN_Index_Type { // @sic R5-221467 sic@ var PDN_Index_Type v_PDN := PDN_3; select (p_DNNType) { case (IMS_DNN){ v_PDN := PDN_1; } case (Emergency_PDN){ v_PDN := PDN_2; } case (URLLC_DNN){ v_PDN := PDN_4; } case (MIOT_DNN){ v_PDN := PDN_5; } case (V2X_DNN){ v_PDN := PDN_6; } } return v_PDN; } /* * @desc Get Pdn Type from the Index to be used in Multi PDN/PDU ATS * @param p_PDN_Index * @return PDU_PDN_DNN_Type * @status APPROVED (NR5GC_IRAT) */ function f_GetMultiPdnTypeFromIndex(PDN_Index_Type p_PDN_Index) return PDU_PDN_DNN_Type { // @sic R5-221467 sic@ var PDU_PDN_DNN_Type v_DNNType := Internet_DNN; select (p_PDN_Index) { case (PDN_1){ v_DNNType := IMS_DNN; } case (PDN_2){ v_DNNType := Emergency_PDN; } case (PDN_4){ v_DNNType := URLLC_DNN; } case (PDN_5){ v_DNNType := MIOT_DNN; } case (PDN_6){ v_DNNType := V2X_DNN; } } return v_DNNType; } /* * @desc Get PDN DNN Type to be used in Multi PDN/PDU ATS from APN * @param p_APN * @return PDU_PDN_DNN_Type * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ function f_GetPDN_DNNTypeFromAPN(octetstring p_APN) return PDU_PDN_DNN_Type { // @sic R5-221467 sic@ var PDU_PDN_DNN_Type v_PDNType := None; if (match (p_APN, f_DomainName_Encode(pc_APN_ID_Internet))) { // @sic R5s210014 sic@ v_PDNType := Internet_DNN; } else if (match (p_APN, f_DomainName_Encode(pc_APN_ID_IMS))) { // @sic R5s210014 sic@ v_PDNType := IMS_DNN; } else if (match (p_APN, f_DomainName_Encode(pc_APN_ID_URLLC))) { v_PDNType := URLLC_DNN; } else if (match (p_APN, f_DomainName_Encode(pc_APN_ID_MIOT))) { v_PDNType := MIOT_DNN; } else if (match (p_APN, f_DomainName_Encode(pc_APN_ID_V2X))) { v_PDNType := V2X_DNN; } else if (f_IsDNNForEmergency(p_APN)) { // this isn't specified in table 4.8.4-1, but is a valid PDU type v_PDNType := Emergency_PDN; } return v_PDNType; } /* * @desc function to get/initialise p_DNN as per PICS * @param p_PDUType * @return charstring * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ function f_GetDNNStringFromPICS(PDU_PDN_DNN_Type p_PDUType) return charstring { var charstring v_DNN; select (p_PDUType) { case (Internet_DNN) { v_DNN := pc_APN_ID_Internet; } case (IMS_DNN) { v_DNN := pc_APN_ID_IMS; } case (URLLC_DNN) { v_DNN := pc_APN_ID_URLLC; } case (MIOT_DNN) { v_DNN := pc_APN_ID_MIOT; } case (V2X_DNN) { v_DNN := pc_APN_ID_V2X; } case (Ethernet_DNN) { // @sic R5-227472 sic@ v_DNN := pc_APN_ID_Ethernet; } // @sic R5s220670 sic@ case else { FatalError(__FILE__, __LINE__, "Unexpected PICS setting in f_GetDNNStringFromPICS"); } } return v_DNN; } /* * @desc Get Default PDN DNN Type to be used in Multi PDN/PDU ATS from PICS * @return PDU_PDN_DNN_Type * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ function f_GetDefaultAPN_DNNType_FromPICS() return PDU_PDN_DNN_Type { // @sic R5-221467 sic@ var PDU_PDN_DNN_Type v_PDNType := None; select (pc_APN_Default_Configuration) { case (internet) { v_PDNType := Internet_DNN; } case (ims) { v_PDNType := IMS_DNN; } case (urllc) { v_PDNType := URLLC_DNN; } case (miot) { v_PDNType := MIOT_DNN; } case (v2x) { v_PDNType := V2X_DNN; } case (ethernet) { // @sic R5-227472 sic@ v_PDNType := Ethernet_DNN; } } return v_PDNType; } /* * @desc Checks DNN to see if it requests emergency PDN, based on f_EUTRA_GetAPNForIMS * @param p_DNNFromReq * @return boolean * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ function f_IsDNNForEmergency(octetstring p_DNNFromReq) return boolean { return match(p_DNNFromReq, f_DomainName_EncodeLabels({"sos"})); } /* * @desc return label for MCC or MNC to be used in APN * @param p_MncMcc * @param p_Digits * @return charstring * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC, NR5GC_IRAT, POS) */ function f_APN_MccMncLabel(charstring p_MncMcc, charstring p_Digits) return charstring { /* in case of the MCC there are 3 digits; for MNC it may be 2 or 3 digits */ var integer v_DigitCnt := lengthof(p_Digits); var charstring v_Label := ""; select (v_DigitCnt) { case (2) { v_Label := p_MncMcc & "0" & p_Digits; } case (3) { v_Label := p_MncMcc & p_Digits; } case else { FatalError(__FILE__, __LINE__, ""); } } return v_Label; } /* * @desc Encode APN acc. to TS 23.003 cl. 9.1 and RFC 1035 cl. 4.1.2 * @param p_LabelList * @return octetstring * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC, NR5GC_IRAT, POS) */ function f_DomainName_EncodeLabels(CharStringList_Type p_LabelList) return octetstring { var octetstring v_EncodedAPN := ''O; var octetstring v_LabelOctets; var integer v_Length; var integer i; for (i := 0; i < lengthof(p_LabelList); i := i + 1) { v_LabelOctets := char2oct(p_LabelList[i]); v_Length := lengthof(v_LabelOctets); v_EncodedAPN := v_EncodedAPN & int2oct(v_Length, 1) & v_LabelOctets; } return v_EncodedAPN; } /* * @desc Encode APN acc. to TS 23.003 cl. 9.1 and RFC 1035 cl. 4.1.2 * @param p_DomainName * @return octetstring * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC, NR5GC_IRAT, POS) */ function f_DomainName_Encode(charstring p_DomainName) return octetstring { var CharStringList_Type v_LabelList := f_StringSplit(p_DomainName, {"."}); return f_DomainName_EncodeLabels(v_LabelList); } //============================================================================ //---------------------------------------------------------------------------- /* * @desc Convert from IMSI, IMEI or IMEISV of type hexstring to octetstring (to be used in f_Imsi2MobileIdentity, f_Imei2MobileIdentity and f_Imeisv2MobileIdentity) * @param p_MobileId * @return octetstring * @status APPROVED (IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_R10_R11, LTE_IRAT, NBIOT, NR5GC, NR5GC_IRAT, POS, SSNITZ, UTRAN) */ function f_ImsiImei2Octetstring(hexstring p_MobileId) return octetstring { var integer v_Length := lengthof(p_MobileId); var integer v_Odd := (v_Length rem 2); var octetstring v_Other := '00'O; var integer I; var integer K; if (v_Odd == 0) { // If length is even v_Length := v_Length + 1; p_MobileId := p_MobileId & 'F'H; // add '1111' on to the end of the IMSI } // Reverse each pair of digits // First digit is not included as it is treated differently K:=0; for (I:=1; I < v_Length - 1; I:=I+2) { v_Other[K] := hex2oct(p_MobileId[I+1] & p_MobileId[I]); K := K + 1; } return v_Other; } //---------------------------------------------------------------------------- /* * @desc Convert from IMSI of type hexstring to NAS MobileIdentity * @param p_IMSI * @return template (value) MobileIdentity * @status APPROVED (IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_R10_R11, LTE_IRAT, NBIOT, NR5GC_IRAT, POS, SSNITZ, UTRAN) */ function f_Imsi2MobileIdentity(hexstring p_IMSI) return template (value) MobileIdentity { var integer v_ImsiLength := lengthof(p_IMSI); var integer v_Odd := (v_ImsiLength rem 2); var octetstring v_Other := f_ImsiImei2Octetstring (p_IMSI); // @sic R5s100092 sic@ var B4_Type v_FirstDigit := hex2bit(p_IMSI[0]); var B1_Type v_OddEvenInd := int2bit(v_Odd, 1); return cds_MobileIdentityImsi_lv(v_FirstDigit, v_OddEvenInd, v_Other); } //---------------------------------------------------------------------------- /* * @desc Convert from IMEI of type hexstring to NAS MobileIdentity * When transmitted by the MS the CD/SD bit is set to 0. * @param p_IMEI * @param p_NAS_IdType (default value: tsc_IdType_IMEI) * @return template (present) MobileIdentity * @status APPROVED (LTE, LTE_A_R10_R11, NBIOT) */ function f_Imei2MobileIdentity(hexstring p_IMEI, NAS_IdType p_NAS_IdType := tsc_IdType_IMEI) return template (present) MobileIdentity // @sic R5s130758 sic@ { var integer v_ImeiLength := lengthof(p_IMEI); var integer v_Odd := (v_ImeiLength rem 2); var octetstring v_Other := f_ImsiImei2Octetstring (substr(p_IMEI, 0, (v_ImeiLength - 1)) & '0'H); // @sic R5s160006 sic@ var B4_Type v_FirstDigit := hex2bit(p_IMEI[0]); var B1_Type v_OddEvenInd := int2bit(v_Odd, 1); return cr_MobileIdentityImei(v_FirstDigit, v_OddEvenInd, v_Other, p_NAS_IdType); // @sic R5s130758 sic@ } //---------------------------------------------------------------------------- /* * @desc Convert from IMEISV of type hexstring to NAS MobileIdentity * @param p_IMEISV * @return template (present) MobileIdentity * @status APPROVED (LTE, NBIOT) */ function f_Imeisv2MobileIdentity(hexstring p_IMEISV) return template (present) MobileIdentity { // @sic R5-131832 sic@ var integer v_ImeiLength := lengthof(p_IMEISV); var integer v_Odd := (v_ImeiLength rem 2); var octetstring v_Other := f_ImsiImei2Octetstring (p_IMEISV); var B4_Type v_FirstDigit := hex2bit(p_IMEISV[0]); var B1_Type v_OddEvenInd := int2bit(v_Odd, 1); return cr_MobileIdentityImeisv(v_FirstDigit, v_OddEvenInd, v_Other); } //---------------------------------------------------------------------------- /* * @desc Convert from Emergency Number of type hexstring to octetstring (to be used in Emergency Number List in e.g. Attach Accept) * @param p_EmgNum * @return octetstring * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC, NR5GC_IRAT, POS) */ function fl_EmgNum2Octetstring(hexstring p_EmgNum) return octetstring { var integer v_Length := lengthof(p_EmgNum); var integer v_Odd := (v_Length rem 2); var octetstring v_Result := '00'O; var integer I; var integer K; if (v_Odd == 1) { // If length is odd v_Length := v_Length + 1; p_EmgNum := p_EmgNum & 'F'H; // add '1111' on to the end of the Emergency Number } // Reverse each pair of digits, note that v_Length is even K:=0; for (I:=0; I < v_Length - 1; I:=I+2) { v_Result[K] := hex2oct(p_EmgNum[I+1] & p_EmgNum[I]); K := K + 1; } return v_Result; } /* * @desc To generate an local emergency number list * @param p_NoOfNums - To specify how many numbers to be included in the list (max = 10) * @param p_NumList * @return template (value) EmergNumList * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC, NR5GC_IRAT, POS) */ function f_Build_EmergNumList(integer p_NoOfNums, EmergencyNumList p_NumList) return template (value) EmergNumList { var integer i; var template (value) EmergNumList v_EmergNum; var octetstring v_LocalNum; var integer v_LocalLength := 0; var integer v_TotalLength := 0; var B7_Type v_ServCat; v_EmergNum.iei := '34'O; for (i := 0; i < p_NoOfNums; i:=i+1) { v_LocalNum := fl_EmgNum2Octetstring (p_NumList[i]); v_LocalLength := lengthof(v_LocalNum); if (i/2 > 0) { v_ServCat := ('00'B & ('00001'B << i)); } else { v_ServCat := ('00'B & ('00001'B << i)); } v_EmergNum.emergNum[i]:= cs_EmergencyLocalNumber(int2oct(v_LocalLength + 1, 1), cs_EmergServCat(v_ServCat), v_LocalNum); v_TotalLength := v_TotalLength + 2 + v_LocalLength; // 1 octet for v_LocalLength + 1 for SCValue + length of number } v_EmergNum.iel := int2oct (v_TotalLength, 1); return v_EmergNum; } /* * @desc To generate an extended emergency number list * @param p_NoOfNums * @param p_NumList * @param p_EENLV (default value: '0'B) * @param p_SubServices (default value: ''O) * @return template (value) ExtdEmergNumList * @status APPROVED (NR5GC) */ function f_Build_ExtdEmergNumList(integer p_NoOfNums, EmergencyNumList p_NumList, B1_Type p_EENLV := '0'B, octetstring p_SubServices := ''O) return template (value) ExtdEmergNumList { var integer i; var template (value) ExtdEmergNumList v_EmergNum; var octetstring v_LocalNum; var integer v_LocalLength := 0; var integer v_TotalLength := 0; v_EmergNum.iei := '7A'O; for (i := 0; i < p_NoOfNums; i:=i+1) { v_LocalNum := fl_EmgNum2Octetstring (p_NumList[i]); v_EmergNum.emergNum[i]:= cs_ExtdEmergNum(v_LocalNum, p_SubServices); v_LocalLength := (lengthof(v_LocalNum)+ 2 + lengthof (p_SubServices)); v_TotalLength := v_TotalLength + v_LocalLength; } v_EmergNum.spareBits := tsc_Spare7; v_EmergNum.extdEmergNumListValidity := p_EENLV; v_EmergNum.iel := int2oct (v_TotalLength + 1, 2); // 1 octet for EENLV return v_EmergNum; } /* * @desc Generation of a new list of local emergency numbers different from existing ones * @param p_NoOfNums .. maximum 20 * @param p_ExistingNums * @return EmergencyNumList .. numbers of 3 decimal digits each * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NR5GC_IRAT, POS) */ function f_Get_EmergencyNumList(integer p_NoOfNums, EmergencyNumList p_ExistingNums) return EmergencyNumList { /* @sic R5s210369 sic@ */ var EmergencyNumList v_NewNumbers; var integer v_Number := 115; // start as implied by LTE test case 11.2.6 @sic R5s141315 sic@ var boolean v_NumberExists; var hexstring v_NumberDigits; var integer i; if ( p_NoOfNums > 20 ) { FatalError(__FILE__, __LINE__, "unsupported number of emg nums") }; // max 20 emg nums may be generated for (i:=0; i the text between the most inner quotes is returned */ var charstring v_Expression := p_Expression; var charstring v_Result; var template charstring v_ExpectedString := pattern p_ExpectedString; var boolean v_MatchResult; var charstring v_CRLF := oct2char('0D'O) & oct2char('0A'O); v_Result := regexp(p_AT_Response, v_Expression, p_Group); v_MatchResult := match(v_Result, v_ExpectedString); if (v_MatchResult == true) { f_SetVerdict(pass,__FILE__, __LINE__, p_Text); } else { f_ErrorLog(__FILE__, __LINE__, v_CRLF & "Value expected: " & p_ExpectedString & v_CRLF & "Value received: " & v_Result); // if anything went wrong, show it f_SetVerdict(fail,__FILE__, __LINE__, p_Text); } } /*---------------------------------------------------------------------------- * @desc Extract UE security capabilities from IEs and store for use later * @param p_UeNetworkCapability * @param p_MsNetworkCapability * @return UE_SecurityCapability * @status APPROVED (ENDC, IMS, IMS_IRAT, LTE, LTE_A_IRAT, LTE_A_PRO, LTE_A_R10_R11, LTE_A_R12, LTE_IRAT, NBIOT, NR5GC, NR5GC_IRAT, POS) */ function f_EPS_FillNAS_SecurityCapability_Common(UE_NetworkCap p_UeNetworkCapability, template (omit) MS_NetworkCap p_MsNetworkCapability) return UE_SecurityCapability { /* @sic R5s110014, R5-190717 Renamed to be re-used by NR sic@ */ var UE_SecurityCapability v_SecurityCapability; var MS_NetworkCap v_MS_NetworkCap; var B8_Type v_GEA := '00000000'B; var integer v_Length := 2; v_SecurityCapability.eeaCap := bit2oct(p_UeNetworkCapability.eeaCap); // @sic R5s180271 Baseline Moving 2018 Phase 1 sic@ v_SecurityCapability.eiaCap := bit2oct(p_UeNetworkCapability.eiaCap); // @sic R5s180271 Baseline Moving 2018 Phase 1 sic@ if (ispresent(p_UeNetworkCapability.ueaCap)) { v_SecurityCapability.ueaCap := bit2oct(p_UeNetworkCapability.ueaCap); // @sic R5s180271 Baseline Moving 2018 Phase 1 sic@ v_Length := v_Length + 2; // if octet 5 is present, 6 will be too @sic R5s100485 sic@ if (ispresent(p_UeNetworkCapability.uiaCap)) { v_SecurityCapability.uiaCap := bit2oct(p_UeNetworkCapability.uiaCap) and4b '7F'O; // @sic R5s100520, R5s180271 Baseline Moving 2018 Phase 1 sic@ } else { v_SecurityCapability.uiaCap := '00'O; // @sic R5s100485 sic@ } } else { v_SecurityCapability.ueaCap := omit; v_SecurityCapability.uiaCap := omit; // @sic R5s100184 sic@ } if (isvalue (p_MsNetworkCapability)) { v_MS_NetworkCap := valueof(p_MsNetworkCapability); if (v_MS_NetworkCap.gea1 == '1'B) { v_GEA := v_GEA or4b '01000000'B; // error corrected in delivery } if (v_MS_NetworkCap.gea2 == '1'B) { v_GEA := v_GEA or4b '00100000'B; // error corrected in delivery } if (v_MS_NetworkCap.gea3 == '1'B) { v_GEA := v_GEA or4b '00010000'B; // error corrected in delivery } if (v_MS_NetworkCap.gea4 == '1'B) { v_GEA := v_GEA or4b '00001000'B; // error corrected in delivery } if (v_MS_NetworkCap.gea5 == '1'B) { v_GEA := v_GEA or4b '00000100'B; // error corrected in delivery } if (v_MS_NetworkCap.gea6 == '1'B) { v_GEA := v_GEA or4b '00000010'B; // error corrected in delivery } if (v_MS_NetworkCap.gea7 == '1'B) { v_GEA := v_GEA or4b '00000001'B; // error corrected in delivery } v_Length := v_Length + 1; v_SecurityCapability.geaCap := bit2oct (v_GEA); // Now store the completed GEA octet if (v_Length == 3) { // UE didn't report any UTRAN capabilities, so set them to 0 @sic R5s100485 sic@ v_Length := 5; v_SecurityCapability.ueaCap := '00'O; v_SecurityCapability.uiaCap := '00'O; } } else {// MS Network Capability not present @sic R5s100184 sic@ v_SecurityCapability.geaCap := omit; // if UE included UTRAN capabilities but they're all zero if (v_SecurityCapability.ueaCap == '00'O and v_SecurityCapability.uiaCap == '00'O) { // @sic R5s130107 sic@ v_SecurityCapability.ueaCap := omit; v_SecurityCapability.uiaCap := omit; v_Length := 2; } } v_SecurityCapability.iel := int2oct (v_Length, 1); // Now store the length return v_SecurityCapability; } /* * @desc Calculate current year from System Time * @return integer * @status APPROVED (LTE, NR5GC, SSNITZ) */ function f_NITZ_GetCurrentYear() return integer { var Struct_tm_Type v_LocalTime; var integer v_TimezoneSeconds; fx_GetSystemTime(v_LocalTime, v_TimezoneSeconds); return v_LocalTime.tm_year + 1900; } /* * @desc Convert current year from integer to 1 octet * @param p_Year * @return O1_Type * @status APPROVED (LTE, NR5GC, SSNITZ) */ function f_NITZ_CurrentYear2Oct(integer p_Year) return O1_Type { return hex2oct(f_SwappedNibbles(p_Year)); } /* * @desc Extract the last 2 digits of the current year (as integer value) * @param p_Year * @return charstring * @status APPROVED (LTE, NR5GC, SSNITZ) */ function f_NITZ_CurrentYear2Str(integer p_Year) return charstring { return int2str(p_Year mod 100); } }