pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/43651?usp=email )
Change subject: smf: Initial HTTP2/SBI support ......................................................................
smf: Initial HTTP2/SBI support
* New library/TS*_Templates.ttcn files are added providing several templates for SBI interface types available from osmo-ttcn3-openapi-generator.git. * Split SMF_Session_CT parts which are only used during 4G tests (Diameter interfaces, S5/S8/S2b GTPv2C interfaces) into its own file SMF_Session_CT_4G. There's usually no need to look at both 4G and 5G specific code at the same time, since usually tests validate one or the other. SMF_Session_CT is left with common stuff, like lifecycle of component and PFCP interface. * Add a new SMF_Session_CT_5G file containing all 5G specific logic, ie. HTTP2 SBI interface handling. * Add a new test in SMF_Tests which makes use of the new SMF_Session_CT_5G logic to emulate a PDU Session request from a 5G UE. Test and infra only validates so far until UE receives the PDU session request after UDM/PCF validation & setup. Further work will be done in follow-up commits. * Adapt open5gs config to use an SCP to route all HTTP2 traffic. This way we can emulate all nodes through a single HTTP2 server, and we emulate the SCP forwarding the messages to the proper destination. Hence, the NRF is disabled.
Related: SYS#7073 Change-Id: I377b748d8da6e9e53a96a85f1c730505793ecea8 --- M library/HTTP2_Functions.ttcn A library/TS29502_Nsmf_PDUSession_Templates.ttcn A library/TS29503_Nudm_SDM_Templates.ttcn A library/TS29512_Npcf_SMPolicyControl_Templates.ttcn A library/TS29518_Namf_Communication_Templates.ttcn A library/TS29571_CommonData_Templates.ttcn M smf/README.md M smf/SMF_Session_CT.ttcn A smf/SMF_Session_CT_4G.ttcn A smf/SMF_Session_CT_5G.ttcn M smf/SMF_Tests.ttcn M smf/expected-results.xml M smf/gen_links.sh M smf/open5gs-nrf.yaml M smf/open5gs-smf.yaml M smf/regen_makefile.sh M smf/testenv.cfg 17 files changed, 2,000 insertions(+), 396 deletions(-)
Approvals: Jenkins Builder: Verified osmith: Looks good to me, but someone else must approve laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved
diff --git a/library/HTTP2_Functions.ttcn b/library/HTTP2_Functions.ttcn index 95e5ea1..83ebdd6 100644 --- a/library/HTTP2_Functions.ttcn +++ b/library/HTTP2_Functions.ttcn @@ -1,10 +1,12 @@ module HTTP2_Functions {
+import from TCCConversion_Functions all; //f_strstr(), f_strstr_oct() + +import from Misc_Helpers all; + import from HTTP2_Types all; import from HTTP2_Templates all;
-import from TCCConversion_Functions all; //f_strstr() - function f_HTTP2_header_list_find_header(HTTP2_header_list headers, charstring header_name) return template (omit) charstring { for (var integer i := 0; i < lengthof(headers); i := i + 1) { @@ -28,5 +30,67 @@ return boundary; }
+type record HTTP2_multipart_part { + HTTP2_header_list headers, + octetstring data +} +type record of HTTP2_multipart_part HTTP2_multipart_part_list; + +private function f_HTTP2_multipart_msg_parse_part_headers(octetstring data) +return HTTP2_header_list { + var HTTP2_header_list li := {}; + var charstring data_str := oct2char(data); + var charstring delim := "\r\n"; + var ro_charstring sp := f_str_split(data_str, delim); + var charstring line_regexp := "([A-Za-z][A-Za-z0-9-]+):\s#()(?+)\s#()"; + for (var integer i := 0; i < lengthof(sp); i := i + 1) { + if (sp[i] == "") { + continue; + } + var charstring header_name := regexp(sp[i], line_regexp, 0); + var charstring header_value := regexp(sp[i], line_regexp, 1); + li := li & { valueof(ts_HTTP2_header_field(header_name, header_value)) }; + } + return li; +} + +private function f_HTTP2_multipart_msg_parse_part(octetstring data) +return HTTP2_multipart_part { + var HTTP2_multipart_part part; + var octetstring delim := char2oct("\r\n\r\n"); + + /* 0..off is headers, off+lengthof(delim)..end is the data. */ + var integer off := f_strstr_oct(data, delim, 0); + var octetstring header := substr(data, 0, off); + off := off + lengthof(delim); + part := { + headers := f_HTTP2_multipart_msg_parse_part_headers(header), + data := substr(data, off, lengthof(data) - off) + } + return part; +} + +function f_HTTP2_multipart_msg_parse(octetstring data, charstring boundary) +return HTTP2_multipart_part_list { + var HTTP2_multipart_part_list li := {}; + var octetstring token := char2oct("--" & boundary); + var ro_octetstring parts; + + /* Split multiparts based on boundary: */ + parts := f_str_oct_split(data, token); + + /* Last chunk (after last boundary) should contain "--\r\n": */ + if (lengthof(parts) < 2 or parts[lengthof(parts) - 1] != char2oct("--\r\n")) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected parsing multipart ", data, " into ", parts)); + } + + /* Parse each part and put it in the list: */ + for (var integer i := 0; i < lengthof(parts) - 1; i := i + 1) { + li := li & { f_HTTP2_multipart_msg_parse_part(parts[i]) }; + } + return li; +} +
} diff --git a/library/TS29502_Nsmf_PDUSession_Templates.ttcn b/library/TS29502_Nsmf_PDUSession_Templates.ttcn new file mode 100644 index 0000000..e34cd10 --- /dev/null +++ b/library/TS29502_Nsmf_PDUSession_Templates.ttcn @@ -0,0 +1,348 @@ +module TS29502_Nsmf_PDUSession_Templates { + +import from TS29502_Nsmf_PDUSession all; + +type TS29502_Nsmf_PDUSession.SmContextCreateData.additionalHsmfSetIdList AdditionalHsmfSetIdList; +type TS29502_Nsmf_PDUSession.SmContextCreateData.additionalSmfSetIdList AdditionalSmfSetIdList; +type TS29502_Nsmf_PDUSession.SmContextCreateData.nrfOauth2Required NrfOauth2Required; + +template (value) SmContextCreateData +ts_SmContextCreateData( + template (omit) TS29502_Nsmf_PDUSession.Supi supi := omit, + template (omit) boolean unauthenticatedSupi := omit, + template (omit) boolean roamingUeInd := omit, + template (omit) TS29502_Nsmf_PDUSession.Pei pei := omit, + template (omit) TS29502_Nsmf_PDUSession.Gpsi gpsi := omit, + template (omit) TS29502_Nsmf_PDUSession.PduSessionId pduSessionId := omit, + template (omit) TS29502_Nsmf_PDUSession.Dnn dnn := omit, + template (omit) TS29502_Nsmf_PDUSession.Dnn selectedDnn := omit, + template (omit) TS29502_Nsmf_PDUSession.Snssai sNssai := omit, + template (omit) TS29502_Nsmf_PDUSession.Snssai altSnssai := omit, + template (omit) TS29502_Nsmf_PDUSession.Snssai hplmnSnssai := omit, + template (omit) TS29502_Nsmf_PDUSession.Snssai altHplmnSnssai := omit, + template (value) TS29502_Nsmf_PDUSession.NfInstanceId servingNfId, + template (omit) TS29502_Nsmf_PDUSession.Guami guami := omit, + template (omit) TS29502_Nsmf_PDUSession.ServiceName serviceName := omit, + template (value) TS29502_Nsmf_PDUSession.PlmnIdNid servingNetwork, + template (omit) RequestType requestType := omit, + template (omit) TS29502_Nsmf_PDUSession.RefToBinaryData n1SmMsg := omit, + template (value) TS29502_Nsmf_PDUSession.AccessType anType, + template (omit) TS29502_Nsmf_PDUSession.AccessType additionalAnType := omit, + template (omit) TS29502_Nsmf_PDUSession.RatType ratType := omit, + template (omit) TS29502_Nsmf_PDUSession.PresenceState presenceInLadn := omit, + template (omit) boolean perLadnDnnSnssaiInd := omit, + template (omit) TS29502_Nsmf_PDUSession.UserLocation ueLocation := omit, + template (omit) TS29502_Nsmf_PDUSession.TimeZone ueTimeZone := omit, + template (omit) TS29502_Nsmf_PDUSession.UserLocation addUeLocation := omit, + template (value) TS29502_Nsmf_PDUSession.Uri smContextStatusUri, + template (omit) TS29502_Nsmf_PDUSession.Uri hSmfUri := omit, + template (omit) TS29502_Nsmf_PDUSession.NfInstanceId hSmfId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfSetId hSmfSetId := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri smfUri := omit, + template (omit) TS29502_Nsmf_PDUSession.NfInstanceId smfId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfSetId smfSetId := omit, + template (omit) record of TS29502_Nsmf_PDUSession.Uri additionalHsmfUri := omit, + template (omit) record of TS29502_Nsmf_PDUSession.NfInstanceId additionalHsmfId := omit, + template (omit) AdditionalHsmfSetIdList additionalHsmfSetIdList := omit, + template (omit) record of TS29502_Nsmf_PDUSession.Uri additionalSmfUri := omit, + template (omit) record of TS29502_Nsmf_PDUSession.NfInstanceId additionalSmfId := omit, + template (omit) AdditionalSmfSetIdList additionalSmfSetIdList := omit, + template (omit) TS29502_Nsmf_PDUSession.PduSessionId oldPduSessionId := omit, + template (omit) record of TS29502_Nsmf_PDUSession.PduSessionId pduSessionsActivateList := omit, + template (omit) EpsPdnCnxContainer ueEpsPdnConnection := omit, + template (omit) HoState hoState := omit, + template (omit) TS29502_Nsmf_PDUSession.NfInstanceId pcfId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfGroupId pcfGroupId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfSetId pcfSetId := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri nrfUri := omit, + template (omit) TS29502_Nsmf_PDUSession.SupportedFeatures supportedFeatures := omit, + template (omit) TS29502_Nsmf_PDUSession.SupportedFeatures anchorSmfFeatures := omit, + template (omit) record of TS29502_Nsmf_PDUSession.SupportedFeatures additionalAnchorSmfFeatures := omit, + template (omit) DnnSelectionMode selMode := omit, + template (omit) TS29502_Nsmf_PDUSession.SmContextCreateData.backupAmfInfo backupAmfInfo := omit, + template (omit) TS29502_Nsmf_PDUSession.TraceData traceData := omit, + template (omit) TS29502_Nsmf_PDUSession.NfGroupId udmGroupId := omit, + template (omit) charstring routingIndicator := omit, + template (omit) integer hNwPubKeyId := omit, + template (omit) EpsInterworkingIndication epsInterworkingInd := omit, + template (omit) boolean indirectForwardingFlag := omit, + template (omit) boolean directForwardingFlag := omit, + template (omit) TS29502_Nsmf_PDUSession.NgRanTargetId targetId := omit, + template (omit) EpsBearerContextStatus epsBearerCtxStatus := omit, + template (omit) boolean cpCiotEnabled := omit, + template (omit) boolean cpOnlyInd := omit, + template (omit) boolean invokeNef := omit, + template (omit) boolean maRequestInd := omit, + template (omit) boolean maNwUpgradeInd := omit, + template (omit) boolean n3gPathSwitchSupportInd := omit, + template (omit) TS29502_Nsmf_PDUSession.RefToBinaryData n2SmInfo := omit, + template (omit) N2SmInfoType n2SmInfoType := omit, + template (omit) TS29502_Nsmf_PDUSession.RefToBinaryData n2SmInfoExt1 := omit, + template (omit) N2SmInfoType n2SmInfoTypeExt1 := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri smContextRef := omit, + template (omit) TS29502_Nsmf_PDUSession.PlmnIdNid smContextSmfPlmnId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfInstanceId smContextSmfId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfSetId smContextSmfSetId := omit, + template (omit) TS29502_Nsmf_PDUSession.NfServiceSetId smContextSmfServiceSetId := omit, + template (omit) TS29502_Nsmf_PDUSession.SbiBindingLevel smContextSmfBinding := omit, + template (omit) UpCnxState upCnxState := omit, + template (omit) TS29502_Nsmf_PDUSession.SmallDataRateStatus smallDataRateStatus := omit, + template (omit) TS29502_Nsmf_PDUSession.ApnRateStatus apnRateStatus := omit, + template (omit) boolean extendedNasSmTimerInd := omit, + template (omit) boolean dlDataWaitingInd := omit, + template (omit) DdnFailureSubs ddnFailureSubs := omit, + template (omit) boolean smfTransferInd := omit, + template (omit) TS29502_Nsmf_PDUSession.NfInstanceId oldSmfId := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri oldSmContextRef := omit, + template (omit) TS29502_Nsmf_PDUSession.WAgfInfo wAgfInfo := omit, + template (omit) TS29502_Nsmf_PDUSession.TngfInfo tngfInfo := omit, + template (omit) TS29502_Nsmf_PDUSession.TwifInfo twifInfo := omit, + template (omit) boolean ranUnchangedInd := omit, + template (omit) boolean samePcfSelectionInd := omit, + template (omit) TS29502_Nsmf_PDUSession.Dnai targetDnai := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri nrfManagementUri := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri nrfDiscoveryUri := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri nrfAccessTokenUri := omit, + template (omit) NrfOauth2Required nrfOauth2Required := omit, + template (omit) charstring smfBindingInfo := omit, + template (omit) TS29502_Nsmf_PDUSession.SmContextCreateData.pvsInfo pvsInfo := omit, + template (omit) boolean onboardingInd := omit, + template (omit) TS29502_Nsmf_PDUSession.Uri oldPduSessionRef := omit, + template (omit) boolean smPolicyNotifyInd := omit, + template (omit) TS29502_Nsmf_PDUSession.PcfUeCallbackInfo pcfUeCallbackInfo := omit, + template (omit) TS29502_Nsmf_PDUSession.SatelliteBackhaulCategory satelliteBackhaulCat := omit, + template (omit) boolean upipSupported := omit, + template (omit) boolean disasterRoamingInd := omit, + template (omit) boolean anchorSmfOauth2Required := omit, + template (omit) boolean smContextSmfOauth2Required := omit, + template (omit) TS29502_Nsmf_PDUSession.GeoSatelliteId geoSatelliteId := omit, + template (omit) TS29502_Nsmf_PDUSession.SatelliteId servingSatelliteId := omit, + template (omit) boolean hrsboAllowedInd := omit, + template (omit) boolean estabRejectionInd := omit, + template (omit) EstablishmentRejectionCause estabRejectionCause := omit, + template (omit) boolean sliceAreaRestrictInd := omit, + template (omit) QosMonitoringPdSupported qosMonitoringPdSupported := omit, + template (omit) TS29502_Nsmf_PDUSession.SmContextCreateData.qosMonitoringPdMethods qosMonitoringPdMethods := omit, + template (omit) QosMonitoringCongestionSupported qosMonitoringCongestionSupported := omit, + template (omit) AvailBitRateMonSupported availBitRateMonSupported := omit, + template (omit) TS29502_Nsmf_PDUSession.UeLevelMeasurementsConfiguration ueLevelMeasConfig := omit, + template (omit) boolean pgwChangeInd := omit, + template (omit) boolean localOffloadingMgtAllowedInd := omit, + template (omit) boolean priorityUserInd := omit +) := { + supi := supi, + unauthenticatedSupi := unauthenticatedSupi, + roamingUeInd := roamingUeInd, + pei := pei, + gpsi := gpsi, + pduSessionId := pduSessionId, + dnn := dnn, + selectedDnn := selectedDnn, + sNssai := sNssai, + altSnssai := altSnssai, + hplmnSnssai := hplmnSnssai, + altHplmnSnssai := altHplmnSnssai, + servingNfId := servingNfId, + guami := guami, + serviceName := serviceName, + servingNetwork := servingNetwork, + requestType := requestType, + n1SmMsg := n1SmMsg, + anType := anType, + additionalAnType := additionalAnType, + ratType := ratType, + presenceInLadn := presenceInLadn, + perLadnDnnSnssaiInd := perLadnDnnSnssaiInd, + ueLocation := ueLocation, + ueTimeZone := ueTimeZone, + addUeLocation := addUeLocation, + smContextStatusUri := smContextStatusUri, + hSmfUri := hSmfUri, + hSmfId := hSmfId, + hSmfSetId := hSmfSetId, + smfUri := smfUri, + smfId := smfId, + smfSetId := smfSetId, + additionalHsmfUri := additionalHsmfUri, + additionalHsmfId := additionalHsmfId, + additionalHsmfSetIdList := additionalHsmfSetIdList, + additionalSmfUri := additionalSmfUri, + additionalSmfId := additionalSmfId, + additionalSmfSetIdList := additionalSmfSetIdList, + oldPduSessionId := oldPduSessionId, + pduSessionsActivateList := pduSessionsActivateList, + ueEpsPdnConnection := ueEpsPdnConnection, + hoState := hoState, + pcfId := pcfId, + pcfGroupId := pcfGroupId, + pcfSetId := pcfSetId, + nrfUri := nrfUri, + supportedFeatures := supportedFeatures, + anchorSmfFeatures := anchorSmfFeatures, + additionalAnchorSmfFeatures := additionalAnchorSmfFeatures, + selMode := selMode, + backupAmfInfo := backupAmfInfo, + traceData := traceData, + udmGroupId := udmGroupId, + routingIndicator := routingIndicator, + hNwPubKeyId := hNwPubKeyId, + epsInterworkingInd := epsInterworkingInd, + indirectForwardingFlag := indirectForwardingFlag, + directForwardingFlag := directForwardingFlag, + targetId := targetId, + epsBearerCtxStatus := epsBearerCtxStatus, + cpCiotEnabled := cpCiotEnabled, + cpOnlyInd := cpOnlyInd, + invokeNef := invokeNef, + maRequestInd := maRequestInd, + maNwUpgradeInd := maNwUpgradeInd, + n3gPathSwitchSupportInd := n3gPathSwitchSupportInd, + n2SmInfo := n2SmInfo, + n2SmInfoType := n2SmInfoType, + n2SmInfoExt1 := n2SmInfoExt1, + n2SmInfoTypeExt1 := n2SmInfoTypeExt1, + smContextRef := smContextRef, + smContextSmfPlmnId := smContextSmfPlmnId, + smContextSmfId := smContextSmfId, + smContextSmfSetId := smContextSmfSetId, + smContextSmfServiceSetId := smContextSmfServiceSetId, + smContextSmfBinding := smContextSmfBinding, + upCnxState := upCnxState, + smallDataRateStatus := smallDataRateStatus, + apnRateStatus := apnRateStatus, + extendedNasSmTimerInd := extendedNasSmTimerInd, + dlDataWaitingInd := dlDataWaitingInd, + ddnFailureSubs := ddnFailureSubs, + smfTransferInd := smfTransferInd, + oldSmfId := oldSmfId, + oldSmContextRef := oldSmContextRef, + wAgfInfo := wAgfInfo, + tngfInfo := tngfInfo, + twifInfo := twifInfo, + ranUnchangedInd := ranUnchangedInd, + samePcfSelectionInd := samePcfSelectionInd, + targetDnai := targetDnai, + nrfManagementUri := nrfManagementUri, + nrfDiscoveryUri := nrfDiscoveryUri, + nrfAccessTokenUri := nrfAccessTokenUri, + nrfOauth2Required := nrfOauth2Required, + smfBindingInfo := smfBindingInfo, + pvsInfo := pvsInfo, + onboardingInd := onboardingInd, + oldPduSessionRef := oldPduSessionRef, + smPolicyNotifyInd := smPolicyNotifyInd, + pcfUeCallbackInfo := pcfUeCallbackInfo, + satelliteBackhaulCat := satelliteBackhaulCat, + upipSupported := upipSupported, + disasterRoamingInd := disasterRoamingInd, + anchorSmfOauth2Required := anchorSmfOauth2Required, + smContextSmfOauth2Required := smContextSmfOauth2Required, + geoSatelliteId := geoSatelliteId, + servingSatelliteId := servingSatelliteId, + hrsboAllowedInd := hrsboAllowedInd, + estabRejectionInd := estabRejectionInd, + estabRejectionCause := estabRejectionCause, + sliceAreaRestrictInd := sliceAreaRestrictInd, + qosMonitoringPdSupported := qosMonitoringPdSupported, + qosMonitoringPdMethods := qosMonitoringPdMethods, + qosMonitoringCongestionSupported := qosMonitoringCongestionSupported, + availBitRateMonSupported := availBitRateMonSupported, + ueLevelMeasConfig := ueLevelMeasConfig, + pgwChangeInd := pgwChangeInd, + localOffloadingMgtAllowedInd := localOffloadingMgtAllowedInd, + priorityUserInd := priorityUserInd +} + +template (value) RefToBinaryData +ts_RefToBinaryData(template (value) charstring contentId) := { + contentId := contentId +} + +template (value) Snssai +ts_Snssai(template (value) integer sst, + template (omit) charstring sd := omit) := { + sst := sst, + sd := sd +} + +template (value) Guami +ts_Guami(template (value) PlmnIdNid plmnId, + template (value) AmfId amfId) := { + plmnId := plmnId, + amfId := amfId +} + +template (value) PlmnId +ts_PlmnId(template (value) Mcc mcc, + template (value) Mnc mnc) := { + mcc := mcc, + mnc := mnc +} + +template (value) PlmnIdNid +ts_PlmnIdNid(template (value) Mcc mcc, + template (value) Mnc mnc, + template (omit) Nid nid := omit) := { + mcc := mcc, + mnc := mnc, + nid := nid +} + +template (value) RatType +ts_RatType(template (value) RatType_enum enum_val) := { + enum_val := enum_val +} + +template (value) UserLocation +ts_UserLocation(template (omit) EutraLocation eutraLocation := omit, + template (omit) NrLocation nrLocation := omit, + template (omit) N3gaLocation n3gaLocation := omit, + template (omit) UtraLocation utraLocation := omit, + template (omit) GeraLocation geraLocation := omit) := { + eutraLocation := eutraLocation, + nrLocation := nrLocation, + n3gaLocation := n3gaLocation, + utraLocation := utraLocation, + geraLocation := geraLocation +} + +template (value) NrLocation +ts_NrLocation(template (value) Tai tai, + template (value) Ncgi ncgi, + template (omit) boolean ignoreNcgi := omit, + template (omit) integer ageOfLocationInformation := omit, + template (omit) DateTime ueLocationTimestamp := omit, + template (omit) charstring geographicalInformation := omit, + template (omit) charstring geodeticInformation := omit, + template (omit) GlobalRanNodeId globalGnbId := omit, + template (omit) NtnTaiInfo ntnTaiInfo := omit) := { + tai := tai, + ncgi := ncgi, + ignoreNcgi := ignoreNcgi, + ageOfLocationInformation := ageOfLocationInformation, + ueLocationTimestamp := ueLocationTimestamp, + geographicalInformation := geographicalInformation, + geodeticInformation := geodeticInformation, + globalGnbId := globalGnbId, + ntnTaiInfo := ntnTaiInfo +} + +template (value) Tai +ts_Tai(template (value) PlmnId plmnId, + template (value) Tac tac, + template (omit) Nid nid := omit) := { + plmnId := plmnId, + tac := tac, + nid := nid +} + +template (value) Ncgi +ts_Ncgi(template (value) PlmnId plmnId, + template (value) NrCellId nrCellId, + template (omit) Nid nid := omit) := { + plmnId := plmnId, + nrCellId := nrCellId, + nid := nid +} + +} diff --git a/library/TS29503_Nudm_SDM_Templates.ttcn b/library/TS29503_Nudm_SDM_Templates.ttcn new file mode 100644 index 0000000..43c85e0 --- /dev/null +++ b/library/TS29503_Nudm_SDM_Templates.ttcn @@ -0,0 +1,326 @@ +module TS29503_Nudm_SDM_Templates { + +import from TS29503_Nudm_SDM all; + +template (value) PduSessionType1 +ts_PduSessionType1(template (value) PduSessionType1_enum enum_val) := { + enum_val := enum_val +} + +type TS29503_Nudm_SDM.PduSessionTypes1.allowedSessionTypes PduSessionType1List; +template (value) PduSessionTypes1 +ts_PduSessionTypes1(template (omit) PduSessionType1 defaultSessionType := omit, + template (omit) PduSessionType1List allowedSessionTypes := omit) := { + defaultSessionType := defaultSessionType, + allowedSessionTypes := allowedSessionTypes +} + +template (value) SscMode1 +ts_SscMode1(template (value) SscMode1_enum enum_val) := { + enum_val := enum_val +} + +type TS29503_Nudm_SDM.SscModes1.allowedSscModes SscMode1List; +template (value) SscModes1 +ts_SscModes1(template (value) SscMode1 defaultSscMode, + template (omit) SscMode1List allowedSscModes := omit) := { + defaultSscMode := defaultSscMode, + allowedSscModes := allowedSscModes +} + +template (value) ArpPriorityLevel +ts_ArpPriorityLevel(template (value) integer val) := { + val := val +} + +template (value) PreemptionCapability +ts_PreemptionCapability(template (value) PreemptionCapability_enum enum_val) := { + enum_val := enum_val +} + +template (value) PreemptionVulnerability +ts_PreemptionVulnerability(template (value) PreemptionVulnerability_enum enum_val) := { + enum_val := enum_val +} + +template (value) Arp +ts_Arp(template (value) ArpPriorityLevel priorityLevel, + template (value) PreemptionCapability preemptCap, + template (value) PreemptionVulnerability preemptVuln) := { + priorityLevel := priorityLevel, + preemptCap := preemptCap, + preemptVuln := preemptVuln +} + +template (value) SubscribedDefaultQos1 +ts_SubscribedDefaultQos1(template (value) FiveQi fiveqi, + template (value) Arp arp, + template (omit) FiveQiPriorityLevel priorityLevel := omit) := { +fiveqi := fiveqi, +arp := arp, +priorityLevel := priorityLevel +} + +template (value) Ambr1 +ts_Ambr1(template (value) BitRate uplink, + template (value) BitRate downlink) := { + uplink := uplink, + downlink := downlink +} + +template (value) DnnConfiguration1 +ts_DnnConfiguration1(template (value) PduSessionTypes1 pduSessionTypes, + template (value) SscModes1 sscModes, + template (omit) IwkEpsInd1 iwkEpsInd := omit, + template (omit) SubscribedDefaultQos1 fivegQosProfile := omit, + template (omit) Ambr1 sessionAmbr := omit, + template (omit) ThreeGppChargingCharacteristics1 threegppChargingCharacteristics := omit, + template (omit) DnnConfiguration1.staticIpAddress staticIpAddress := omit, + template (omit) UpSecurity1 upSecurity := omit, + template (omit) PduSessionContinuityInd1 pduSessionContinuityInd := omit, + template (omit) NefId1 niddNefId := omit, + template (omit) NiddInformation1 niddInfo := omit, + template (omit) boolean redundantSessionAllowed := omit, + template (omit) AcsInfo1 acsInfo := omit, + template (omit) DnnConfiguration1.ipv4FrameRouteList ipv4FrameRouteList := omit, + template (omit) DnnConfiguration1.ipv6FrameRouteList ipv6FrameRouteList := omit, + template (omit) boolean atsssAllowed := omit, + template (omit) boolean secondaryAuth := omit, + template (omit) boolean uavSecondaryAuth := omit, + template (omit) boolean dnAaaIpAddressAllocation := omit, + template (omit) IpAddress1 dnAaaAddress := omit, + template (omit) DnnConfiguration1.additionalDnAaaAddresses additionalDnAaaAddresses := omit, + template (omit) Fqdn1 dnAaaFqdn := omit, + template (omit) charstring iptvAccCtrlInfo := omit, + template (omit) IpIndex1 ipv4Index := omit, + template (omit) IpIndex1 ipv6Index := omit, + template (omit) EcsAddrConfigInfo1 ecsAddrConfigInfo := omit, + template (omit) DnnConfiguration1.additionalEcsAddrConfigInfos additionalEcsAddrConfigInfos := omit, + template (omit) SharedDataId1 sharedEcsAddrConfigInfo := omit, + template (omit) DnnConfiguration1.additionalSharedEcsAddrConfigInfoIds additionalSharedEcsAddrConfigInfoIds := omit, + template (omit) boolean easDiscoveryAuthorized := omit, + template (omit) boolean onboardingInd := omit, + template (omit) AerialUeIndication1 aerialUeInd := omit, + template (omit) integer subscribedMaxIpv6PrefixSize := omit, + template (omit) boolean hrSboAuthorized := omit, + template (omit) DnnConfiguration1.requiredUpfFunctionList requiredUpfFunctionList := omit, + template (omit) DnnConfiguration1.prefUpfFunctionList prefUpfFunctionList := omit, + template (omit) DnnConfiguration1.vlanTagAllowed vlanTagAllowed := omit, + template (omit) DnnConfiguration1.vlanTagHandlingInfo vlanTagHandlingInfo := omit, + template (omit) boolean localOffloadingMngtInd := omit +) := { + pduSessionTypes := pduSessionTypes, + sscModes := sscModes, + iwkEpsInd := iwkEpsInd, + fivegQosProfile := fivegQosProfile, + sessionAmbr := sessionAmbr, + threegppChargingCharacteristics := threegppChargingCharacteristics, + staticIpAddress := staticIpAddress, + upSecurity := upSecurity, + pduSessionContinuityInd := pduSessionContinuityInd, + niddNefId := niddNefId, + niddInfo := niddInfo, + redundantSessionAllowed := redundantSessionAllowed, + acsInfo := acsInfo, + ipv4FrameRouteList := ipv4FrameRouteList, + ipv6FrameRouteList := ipv6FrameRouteList, + atsssAllowed := atsssAllowed, + secondaryAuth := secondaryAuth, + uavSecondaryAuth := uavSecondaryAuth, + dnAaaIpAddressAllocation := dnAaaIpAddressAllocation, + dnAaaAddress := dnAaaAddress, + additionalDnAaaAddresses := additionalDnAaaAddresses, + dnAaaFqdn := dnAaaFqdn, + iptvAccCtrlInfo := iptvAccCtrlInfo, + ipv4Index := ipv4Index, + ipv6Index := ipv6Index, + ecsAddrConfigInfo := ecsAddrConfigInfo, + additionalEcsAddrConfigInfos := additionalEcsAddrConfigInfos, + sharedEcsAddrConfigInfo := sharedEcsAddrConfigInfo, + additionalSharedEcsAddrConfigInfoIds := additionalSharedEcsAddrConfigInfoIds, + easDiscoveryAuthorized := easDiscoveryAuthorized, + onboardingInd := onboardingInd, + aerialUeInd := aerialUeInd, + subscribedMaxIpv6PrefixSize := subscribedMaxIpv6PrefixSize, + hrSboAuthorized := hrSboAuthorized, + requiredUpfFunctionList := requiredUpfFunctionList, + prefUpfFunctionList := prefUpfFunctionList, + vlanTagAllowed := vlanTagAllowed, + vlanTagHandlingInfo := vlanTagHandlingInfo, + localOffloadingMngtInd := localOffloadingMngtInd +} + + +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.dnnConfigurations DnnConfigurationMap; +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.sharedVnGroupDataIds SharedVnGroupDataIdMap; +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.odbExemptedDnnData OdbExemptedDnnDataMap; +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.expectedUeBehavioursList ExpectedUeBehavioursMap; +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.expectedUeBehaviourData ExpectedUeBehaviourDataMap; +//type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.expectedUeBehaviourData.additionalProperties ExpectedUeBehaviourData1Map; +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.appSpecificExpectedUeBehaviourData AppSpecificExpectedUeBehaviourDataMap; +//type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.appSpecificExpectedUeBehaviourData.additionalProperties AppSpecificExpectedUeBehaviourData1Map; +type TS29503_Nudm_SDM.SessionManagementSubscriptionData1.suggestedPacketNumDlList SuggestedPacketNumDlMap; + +template (value) SessionManagementSubscriptionData1 +ts_SessionManagementSubscriptionData1(template (value) Snssai1 singleNssai, + template (omit) DnnConfigurationMap dnnConfigurations := omit, + template (omit) record of GroupId1 internalGroupIds := omit, + template (omit) SharedVnGroupDataIdMap sharedVnGroupDataIds := omit, + template (omit) SharedDataId1 sharedDnnConfigurationsId := omit, + template (omit) OdbPacketServices1 odbPacketServices := omit, + template (omit) OdbExemptedDnnDataMap odbExemptedDnnData := omit, + template (omit) TraceData1 traceData := omit, + template (omit) SharedDataId1 sharedTraceDataId := omit, + template (omit) ExpectedUeBehavioursMap expectedUeBehavioursList := omit, + template (omit) ExpectedUeBehaviourDataMap expectedUeBehaviourData := omit, + template (omit) AppSpecificExpectedUeBehaviourDataMap appSpecificExpectedUeBehaviourData := omit, + template (omit) SuggestedPacketNumDlMap suggestedPacketNumDlList := omit, + template (omit) ThreeGppChargingCharacteristics1 threegppChargingCharacteristics := omit, + template (omit) NfGroupId1 chfGroupId := omit, + template (omit) NsacAdmissionMode1 nsacMode := omit, + template (omit) DurationSec1 sessInactTimer := omit, + template (omit) SupportedFeatures1 supportedFeatures := omit, + template (omit) record of SharedDataId1 additionalSharedDnnConfigurationsIds := omit, + template (omit) UeLevelMeasurementsConfiguration1 ueLevelMeasConfig := omit) := { + singleNssai := singleNssai, + dnnConfigurations := dnnConfigurations, + internalGroupIds := internalGroupIds, + sharedVnGroupDataIds := sharedVnGroupDataIds, + sharedDnnConfigurationsId := sharedDnnConfigurationsId, + odbPacketServices := odbPacketServices, + odbExemptedDnnData := odbExemptedDnnData, + traceData := traceData, + sharedTraceDataId := sharedTraceDataId, + expectedUeBehavioursList := expectedUeBehavioursList, + expectedUeBehaviourData := expectedUeBehaviourData, + appSpecificExpectedUeBehaviourData := appSpecificExpectedUeBehaviourData, + suggestedPacketNumDlList := suggestedPacketNumDlList, + threegppChargingCharacteristics := threegppChargingCharacteristics, + chfGroupId := chfGroupId, + nsacMode := nsacMode, + sessInactTimer := sessInactTimer, + supportedFeatures := supportedFeatures, + additionalSharedDnnConfigurationsIds := additionalSharedDnnConfigurationsIds, + ueLevelMeasConfig := ueLevelMeasConfig +} + +type TS29503_Nudm_SDM.SmSubsData1.field1 SessionManagementSubscriptionData1List; +template (value) SmSubsData1 +ts_SmSubsData1(template (value) SessionManagementSubscriptionData1List field1) := { + field1 := field1 +} + +type TS29503_Nudm_SDM.SdmSubscription1.expectedUeBehaviourThresholds ExpectedUeBehaviourThresholdsMap; +template (present) SdmSubscription1 +tr_SdmSubscription1(template (present) NfInstanceId1 nfInstanceId := ?, + template boolean implicitUnsubscribe := *, + template DateTime1 expires := *, + template (present) Uri1 callbackReference := ?, + template ServiceName1 amfServiceName := *, + template (present) SdmSubscription1.monitoredResourceUris monitoredResourceUris := ?, + template Snssai1 singleNssai := *, + template Dnn1 dnn := *, + template charstring subscriptionId := *, + template PlmnId1 plmnId := *, + template boolean immediateReport := *, + template ImmediateReport1 report := *, + template SupportedFeatures1 supportedFeatures := *, + template ContextInfo1 contextInfo := *, + template boolean nfChangeFilter := *, + template boolean uniqueSubscription := *, + template SdmSubscription1.resetIds resetIds := *, + template UeContextInSmfDataSubFilter1 ueConSmfDataSubFilter := *, + template SdmSubscription1.adjacentPlmns adjacentPlmns := *, + template boolean disasterRoamingInd := *, + template Uri1 dataRestorationCallbackUri := *, + template boolean udrRestartInd := *, + template DateTime1 lastSynchronizationTime := *, + template ExpectedUeBehaviourThresholdsMap expectedUeBehaviourThresholds := *, + template Guami1 guami := *) := { + nfInstanceId := nfInstanceId, + implicitUnsubscribe := implicitUnsubscribe, + expires := expires, + callbackReference := callbackReference, + amfServiceName := amfServiceName, + monitoredResourceUris := monitoredResourceUris, + singleNssai := singleNssai, + dnn := dnn, + subscriptionId := subscriptionId, + plmnId := plmnId, + immediateReport := immediateReport, + report := report, + supportedFeatures := supportedFeatures, + contextInfo := contextInfo, + nfChangeFilter := nfChangeFilter, + uniqueSubscription := uniqueSubscription, + resetIds := resetIds, + ueConSmfDataSubFilter := ueConSmfDataSubFilter, + adjacentPlmns := adjacentPlmns, + disasterRoamingInd := disasterRoamingInd, + dataRestorationCallbackUri := dataRestorationCallbackUri, + udrRestartInd := udrRestartInd, + lastSynchronizationTime := lastSynchronizationTime, + expectedUeBehaviourThresholds := expectedUeBehaviourThresholds, + guami := guami +} +template (value) SdmSubscription1 +ts_SdmSubscription1(template (value) NfInstanceId1 nfInstanceId, + template (omit) boolean implicitUnsubscribe := omit, + template (omit) DateTime1 expires := omit, + template (value) Uri1 callbackReference, + template (omit) ServiceName1 amfServiceName := omit, + template (value) SdmSubscription1.monitoredResourceUris monitoredResourceUris, + template (omit) Snssai1 singleNssai := omit, + template (omit) Dnn1 dnn := omit, + template (omit) charstring subscriptionId := omit, + template (omit) PlmnId1 plmnId := omit, + template (omit) boolean immediateReport := omit, + template (omit) ImmediateReport1 report := omit, + template (omit) SupportedFeatures1 supportedFeatures := omit, + template (omit) ContextInfo1 contextInfo := omit, + template (omit) boolean nfChangeFilter := omit, + template (omit) boolean uniqueSubscription := omit, + template (omit) SdmSubscription1.resetIds resetIds := omit, + template (omit) UeContextInSmfDataSubFilter1 ueConSmfDataSubFilter := omit, + template (omit) SdmSubscription1.adjacentPlmns adjacentPlmns := omit, + template (omit) boolean disasterRoamingInd := omit, + template (omit) Uri1 dataRestorationCallbackUri := omit, + template (omit) boolean udrRestartInd := omit, + template (omit) DateTime1 lastSynchronizationTime := omit, + template (omit) ExpectedUeBehaviourThresholdsMap expectedUeBehaviourThresholds := omit, + template (omit) Guami1 guami := omit) := { + nfInstanceId := nfInstanceId, + implicitUnsubscribe := implicitUnsubscribe, + expires := expires, + callbackReference := callbackReference, + amfServiceName := amfServiceName, + monitoredResourceUris := monitoredResourceUris, + singleNssai := singleNssai, + dnn := dnn, + subscriptionId := subscriptionId, + plmnId := plmnId, + immediateReport := immediateReport, + report := report, + supportedFeatures := supportedFeatures, + contextInfo := contextInfo, + nfChangeFilter := nfChangeFilter, + uniqueSubscription := uniqueSubscription, + resetIds := resetIds, + ueConSmfDataSubFilter := ueConSmfDataSubFilter, + adjacentPlmns := adjacentPlmns, + disasterRoamingInd := disasterRoamingInd, + dataRestorationCallbackUri := dataRestorationCallbackUri, + udrRestartInd := udrRestartInd, + lastSynchronizationTime := lastSynchronizationTime, + expectedUeBehaviourThresholds := expectedUeBehaviourThresholds, + guami := guami +} + +template (value) Snssai1 +ts_Snssai1(template (value) integer sst, + template (omit) charstring sd := omit) := { + sst := sst, + sd := sd +} + +} diff --git a/library/TS29512_Npcf_SMPolicyControl_Templates.ttcn b/library/TS29512_Npcf_SMPolicyControl_Templates.ttcn new file mode 100644 index 0000000..4e12839 --- /dev/null +++ b/library/TS29512_Npcf_SMPolicyControl_Templates.ttcn @@ -0,0 +1,223 @@ +module TS29512_Npcf_SMPolicyControl_Templates { + +import from TS29512_Npcf_SMPolicyControl all; + +template (present) SmPolicyContextData1 +tr_SmPolicyContextData1(template AccNetChId1 accNetChId := *, + template AccNetChargingAddress1 chargEntityAddr := *, + template Gpsi1 gpsi := *, + template (present) Supi1 supi := ?, + template boolean invalidSupi := *, + template record of GroupId1 interGrpIds := *, + template (present) PduSessionId1 pduSessionId := ?, + template (present) PduSessionType1 pduSessionType := ?, + template charstring chargingcharacteristics := *, + template (present) Dnn1 dnn := ?, + template DnnSelectionMode1 dnnSelMode := *, + template (present) Uri1 notificationUri := ?, + template AccessType1 accessType := *, + template RatType1 ratType := *, + template AdditionalAccessInfo1 addAccessInfo := *, + template PlmnIdNid1 servingNetwork := *, + template UserLocation1 userLocationInfo := *, + template TimeZone1 ueTimeZone := *, + template Pei1 pei := *, + template Ipv4Addr1 ipv4Address := *, + template Ipv6Prefix1 ipv6AddressPrefix := *, + template charstring ipDomain := *, + template Ambr1 subsSessAmbr := *, + template charstring authProfIndex := *, + template SubscribedDefaultQos1 subsDefQos := *, + template VplmnQos1 vplmnQos := *, + template integer numOfPackFilter := *, + template boolean online := *, + template boolean offline := *, + template boolean threegppPsDataOffStatus := *, + template boolean refQosIndication := *, + template TraceData1 traceReq := *, + template (present) Snssai1 sliceInfo := ?, + template Snssai1 altSliceInfo := *, + template QosFlowUsage1 qosFlowUsage := *, + template ServingNfIdentity1 servNfId := *, + template SupportedFeatures1 suppFeat := *, + template NfInstanceId1 smfId := *, + template DateTime1 recoveryTime := *, + template MaPduIndication1 maPduInd := *, + template AtsssCapability1 atsssCapab := *, + template SmPolicyContextData1.atsssCapabs atsssCapabs := *, + template SmPolicyContextData1.ipv4FrameRouteList ipv4FrameRouteList := *, + template SmPolicyContextData1.ipv6FrameRouteList ipv6FrameRouteList := *, + template SatelliteBackhaulCategory1 satBackhaulCategory := *, + template PcfUeCallbackInfo1 pcfUeInfo := *, + template SmPolicyContextData1.pvsInfo pvsInfo := *, + template boolean onboardInd := *, + template SmPolicyContextData1.nwdafDatas nwdafDatas := *, + template UrspEnforcementInfo1 urspEnfInfo := *, + template SscMode1 sscMode := *, + template Dnn1 ueReqDnn := *, + template PduSessionType1 ueReqPduSessionType := *, + template boolean hrsboInd := *, + template boolean locOffloadInd := *, + template UePolicyTransferFailureCause1 uePolFailReport := *, + template boolean urspProvSuppInd := *, + template boolean mpxMediaInd := *, + template SmPolicyContextData1.trafficDescriptors trafficDescriptors := * +) := { + accNetChId := accNetChId, + chargEntityAddr := chargEntityAddr, + gpsi := gpsi, + supi := supi, + invalidSupi := invalidSupi, + interGrpIds := interGrpIds, + pduSessionId := pduSessionId, + pduSessionType := pduSessionType, + chargingcharacteristics := chargingcharacteristics, + dnn := dnn, + dnnSelMode := dnnSelMode, + notificationUri := notificationUri, + accessType := accessType, + ratType := ratType, + addAccessInfo := addAccessInfo, + servingNetwork := servingNetwork, + userLocationInfo := userLocationInfo, + ueTimeZone := ueTimeZone, + pei := pei, + ipv4Address := ipv4Address, + ipv6AddressPrefix := ipv6AddressPrefix, + ipDomain := ipDomain, + subsSessAmbr := subsSessAmbr, + authProfIndex := authProfIndex, + subsDefQos := subsDefQos, + vplmnQos := vplmnQos, + numOfPackFilter := numOfPackFilter, + online := online, + offline := offline, + threegppPsDataOffStatus := threegppPsDataOffStatus, + refQosIndication := refQosIndication, + traceReq := traceReq, + sliceInfo := sliceInfo, + altSliceInfo := altSliceInfo, + qosFlowUsage := qosFlowUsage, + servNfId := servNfId, + suppFeat := suppFeat, + smfId := smfId, + recoveryTime := recoveryTime, + maPduInd := maPduInd, + atsssCapab := atsssCapab, + atsssCapabs := atsssCapabs, + ipv4FrameRouteList := ipv4FrameRouteList, + ipv6FrameRouteList := ipv6FrameRouteList, + satBackhaulCategory := satBackhaulCategory, + pcfUeInfo := pcfUeInfo, + pvsInfo := pvsInfo, + onboardInd := onboardInd, + nwdafDatas := nwdafDatas, + urspEnfInfo := urspEnfInfo, + sscMode := sscMode, + ueReqDnn := ueReqDnn, + ueReqPduSessionType := ueReqPduSessionType, + hrsboInd := hrsboInd, + locOffloadInd := locOffloadInd, + uePolFailReport := uePolFailReport, + urspProvSuppInd := urspProvSuppInd, + mpxMediaInd := mpxMediaInd, + trafficDescriptors := trafficDescriptors +} + +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.sessRules SessRulesMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.pccRules PccRulesNullableMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.qosDecs QosDecsMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.chgDecs ChgDecsNullableMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.traffContDecs TraffContDecsMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.umDecs UmDecsNullableMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.qosChars QosCharsMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.qosMonDecs QosMonDecsNullableMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.conds ConditionData1NullableMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.policyCtrlReqTriggers PolicyCtrlReqTriggersMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.praInfos PresenceInfoRm1NullableMap; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.vplmnOffloadInfos VplmnOffloadingInfo1Map; +type TS29512_Npcf_SMPolicyControl.SmPolicyDecision1.locOffloadInfos LocalOffloadingManagementInfo1Map; + +template (value) SmPolicyDecision1 +ts_SmPolicyDecision1(template (omit) SessRulesMap sessRules := omit, + template (omit) PccRulesNullableMap pccRules := omit, + template (omit) boolean pcscfRestIndication := omit, + template (omit) QosDecsMap qosDecs := omit, + template (omit) ChgDecsNullableMap chgDecs := omit, + template (omit) ChargingInformation1 chargingInfo := omit, + template (omit) NfGroupId1 chfGroupId := omit, + template (omit) TraffContDecsMap traffContDecs := omit, + template (omit) UmDecsNullableMap umDecs := omit, + template (omit) QosCharsMap qosChars := omit, + template (omit) QosMonDecsNullableMap qosMonDecs := omit, + template (omit) DurationSec1 reflectiveQoSTimer := omit, + template (omit) ConditionData1NullableMap conds := omit, + template (omit) DateTime1 revalidationTime := omit, + template (omit) boolean offline := omit, + template (omit) boolean online := omit, + template (omit) boolean offlineChOnly := omit, + template (omit) PolicyCtrlReqTriggersMap policyCtrlReqTriggers := omit, + template (omit) SmPolicyDecision1.lastReqRuleData lastReqRuleData := omit, + template (omit) RequestedUsageData1 lastReqUsageData := omit, + template (omit) PresenceInfoRm1NullableMap praInfos := omit, + template (omit) IpIndex1 ipv4Index := omit, + template (omit) IpIndex1 ipv6Index := omit, + template (omit) QosFlowUsage1 qosFlowUsage := omit, + template (omit) SmPolicyDecision1.qosMonCapRepoTypes qosMonCapRepoTypes := omit, + template (omit) SmPolicyAssociationReleaseCause1 relCause := omit, + template (omit) SupportedFeatures1 suppFeat := omit, + template (omit) BridgeManagementContainer1 tsnBridgeManCont := omit, + template (omit) PortManagementContainer1 tsnPortManContDstt := omit, + template (omit) SmPolicyDecision1.tsnPortManContNwtts tsnPortManContNwtts := omit, + template (omit) Uri1 tscNotifUri := omit, + template (omit) charstring tscNotifCorreId := omit, + template (omit) boolean redSessIndication := omit, + template (omit) UePolicyContainer1 uePolCont := omit, + template (omit) SliceUsgCtrlInfo1 sliceUsgCtrlInfo := omit, + template (omit) VplmnOffloadingInfo1Map vplmnOffloadInfos := omit, + template (omit) LocalOffloadingManagementInfo1Map locOffloadInfos := omit, + template (omit) VplmnDlAmbr1 vplmnDlAmbr := omit, + template (omit) PcSessionRecoveryStatus1 sessionRecovStatus:= omit +) := { + sessRules := sessRules, + pccRules := pccRules, + pcscfRestIndication := pcscfRestIndication, + qosDecs := qosDecs, + chgDecs := chgDecs, + chargingInfo := chargingInfo, + chfGroupId := chfGroupId, + traffContDecs := traffContDecs, + umDecs := umDecs, + qosChars := qosChars, + qosMonDecs := qosMonDecs, + reflectiveQoSTimer := reflectiveQoSTimer, + conds := conds, + revalidationTime := revalidationTime, + offline := offline, + online := online, + offlineChOnly := offlineChOnly, + policyCtrlReqTriggers := policyCtrlReqTriggers, + lastReqRuleData := lastReqRuleData, + lastReqUsageData := lastReqUsageData, + praInfos := praInfos, + ipv4Index := ipv4Index, + ipv6Index := ipv6Index, + qosFlowUsage := qosFlowUsage, + qosMonCapRepoTypes := qosMonCapRepoTypes, + relCause := relCause, + suppFeat := suppFeat, + tsnBridgeManCont := tsnBridgeManCont, + tsnPortManContDstt := tsnPortManContDstt, + tsnPortManContNwtts := tsnPortManContNwtts, + tscNotifUri := tscNotifUri, + tscNotifCorreId := tscNotifCorreId, + redSessIndication := redSessIndication, + uePolCont := uePolCont, + sliceUsgCtrlInfo := sliceUsgCtrlInfo, + vplmnOffloadInfos := vplmnOffloadInfos, + locOffloadInfos := locOffloadInfos, + vplmnDlAmbr := vplmnDlAmbr, + sessionRecovStatus := sessionRecovStatus + } + +} diff --git a/library/TS29518_Namf_Communication_Templates.ttcn b/library/TS29518_Namf_Communication_Templates.ttcn new file mode 100644 index 0000000..acba933 --- /dev/null +++ b/library/TS29518_Namf_Communication_Templates.ttcn @@ -0,0 +1,65 @@ +module TS29518_Namf_Communication_Templates { + +import from TS29518_Namf_Communication all; + + +template (present) N1N2MessageTransferReqData +tr_N1N2MessageTransferReqData(template (omit) N1MessageContainer n1MessageContainer := omit, + template (omit) N2InfoContainer n2InfoContainer := omit, + template (omit) RefToBinaryData mtData := omit, + template (omit) boolean skipInd := omit, + template (omit) boolean lastMsgIndication := omit, + template (omit) PduSessionId pduSessionId := omit, + template (omit) CorrelationID lcsCorrelationId := omit, + template (omit) LMFIdentification servingLMFIdentification := omit, + template (omit) Ppi ppi := omit, + template (omit) Arp arp := omit, + template (omit) FiveQi fiveqi := omit, + template (omit) Uri n1n2FailureTxfNotifURI := omit, + template (omit) boolean smfReallocationInd := omit, + template (omit) AreaOfValidity areaOfValidity := omit, + template (omit) SupportedFeatures supportedFeatures := omit, + template (omit) Guami oldGuami := omit, + template (omit) boolean maAcceptedInd := omit, + template (omit) boolean extBufSupport := omit, + template (omit) AccessType targetAccess := omit, + template (omit) NfInstanceId nfId := omit, + template (omit) boolean pruInd := omit, + template (omit) PduSessionPriority pduSessionPrio := omit) := { + n1MessageContainer := n1MessageContainer, + n2InfoContainer := n2InfoContainer, + mtData := mtData, + skipInd := skipInd, + lastMsgIndication := lastMsgIndication, + pduSessionId := pduSessionId, + lcsCorrelationId := lcsCorrelationId, + servingLMFIdentification := servingLMFIdentification, + ppi := ppi, + arp := arp, + fiveqi := fiveqi, + n1n2FailureTxfNotifURI := n1n2FailureTxfNotifURI, + smfReallocationInd := smfReallocationInd, + areaOfValidity := areaOfValidity, + supportedFeatures := supportedFeatures, + oldGuami := oldGuami, + maAcceptedInd := maAcceptedInd, + extBufSupport := extBufSupport, + targetAccess := targetAccess, + nfId := nfId, + pruInd := pruInd, + pduSessionPrio:= pduSessionPrio +} + +template (value) N1N2MessageTransferCause +ts_N1N2MessageTransferCause(N1N2MessageTransferCause_enum enum_val) := { + enum_val := enum_val +} + +template (value) N1N2MessageTransferRspData +ts_N1N2MessageTransferRspData(template (value) N1N2MessageTransferCause cause, + template (omit) SupportedFeatures supportedFeatures := omit) := { + cause := cause, + supportedFeatures := supportedFeatures +} + +} diff --git a/library/TS29571_CommonData_Templates.ttcn b/library/TS29571_CommonData_Templates.ttcn new file mode 100644 index 0000000..7accd38 --- /dev/null +++ b/library/TS29571_CommonData_Templates.ttcn @@ -0,0 +1,14 @@ +module TS29571_CommonData_Templates { + +import from TS29571_CommonData all; + +template (value) PlmnIdNid +ts_PlmnIdNid(template (value) Mcc mcc, + template (value) Mnc mnc, + template (omit) Nid nid := omit) := { + mcc := mcc, + mnc := mnc, + nid := nid +} + +} diff --git a/smf/README.md b/smf/README.md index 716c38e..0dfee3a 100644 --- a/smf/README.md +++ b/smf/README.md @@ -13,13 +13,18 @@ rankdir=LR; ATS [label="ATS\nSMF_Tests.ttcn"]; SMF [label="AMF\open5gs-smfd",shape="box"]; - NRF [label="SMF\nopen5gs-nrfd"];
- ATS -> SMF [label="N11"]; - ATS -> SMF [label="N4"]; - ATS -> SMF [label="Gx"]; - ATS -> SMF [label="Gy"]; - ATS -> SMF [label="S6b"]; - SMF -> NRF [label="SBI"]; + ATS -> SMF [dir="both",label="N4 (PFCP)"]; + ATS -> SMF [dir="both",label="Gx (Diameter)"]; + ATS -> SMF [dir="both",label="Gy (Diameter)"]; + ATS -> SMF [dir="both",label="S6b (Diameter)"]; + #4G: + ATS -> SMF [label="S5/S8 (GTPv2C)"]; + ATS -> SMF [label="S2b (GTPv2C)"]; + # 5G: + ATS -> SMF [label="Nsmf (SBI)"]; + SMF -> ATS [label="Namf (SBI, over SCP)"]; + SMF -> ATS [label="Nudm (SBI, over SCP)"]; + SMF -> ATS [label="Npcf (SBI, over SCP)"]; } %} diff --git a/smf/SMF_Session_CT.ttcn b/smf/SMF_Session_CT.ttcn index 6114167..11e9f3a 100644 --- a/smf/SMF_Session_CT.ttcn +++ b/smf/SMF_Session_CT.ttcn @@ -9,19 +9,12 @@ import from Misc_Helpers all;
import from GTPv1U_Emulation all; - import from GTPv2_Types all; import from GTPv2_Templates all; import from GTPv2_Emulation all;
-import from DNS_Helpers all; - import from DIAMETER_Types all; import from DIAMETER_Templates all; -import from DIAMETER_ts29_212_Templates all; -import from DIAMETER_ts29_272_Templates all; -import from DIAMETER_ts29_273_Templates all; -import from DIAMETER_ts32_299_Templates all; import from DIAMETER_Emulation all;
import from PFCP_Types all; @@ -31,18 +24,20 @@
import from NTP_Functions all;
+import from HTTP2_Adapter all; +import from HTTP2_Server_Emulation all; + import from Mutex all;
+import from SMF_Session_CT_4G all; +import from SMF_Session_CT_5G all; import from SMF_Tests all;
-const integer DIA_Gx := 0; -const integer DIA_Gy := 1; -const integer DIA_S6b := 2; - const OCT8 c_SEID0 := '0000000000000000'O;
/* per-session component; we typically have 1..N per testcase */ -type component SMF_Session_CT extends GTP2_ConnHdlr, GTP1U_ConnHdlr, DIAMETER_ConnHdlr, PFCP_ConnHdlr, MutexCT { +type component SMF_Session_CT extends GTP2_ConnHdlr, GTP1U_ConnHdlr, DIAMETER_ConnHdlr, + PFCP_ConnHdlr, MutexCT, HTTP2_CT, HTTP2_ConnHdlr { var SessionPars g_pars;
/* GTP-U IPv4 address remote sie */ @@ -58,6 +53,14 @@ var PDU_DIAMETER g_rx_gy; }
+type record SessionParsGy { + /* In seconds. 0 => disabled, !0 => grant over CC-Time period */ + integer validity_time, + + /* Result-Code to use when sending Gy CCA, usually DIAMETER_SUCCESS */ + DIAMETER_Resultcode cca_res_code +}; + type record BearerConfig { /* EPS Bearer ID */ uint4_t ebi optional, @@ -67,14 +70,6 @@ OCT4 teid_remote optional };
-type record SessionParsGy { - /* In seconds. 0 => disabled, !0 => grant over CC-Time period */ - integer validity_time, - - /* Result-Code to use when sending Gy CCA, usually DIAMETER_SUCCESS */ - DIAMETER_Resultcode cca_res_code -}; - type record FTeids { F_TEID local, F_TEID remote optional @@ -160,6 +155,7 @@ /* configuration data for a given Session */ type record SessionPars { hexstring imsi, + charstring imsi_str, hexstring msisdn optional, // serving network GTP2C_RAT_Type rat_type, @@ -195,6 +191,7 @@ GTP2C_PDN_Type pdn_type := GTP2C_PDN_IPv4, template (value) PfcpParameters pfcp_pars := f_t_PfcpParams(1)) := { imsi := imsi, + imsi_str := f_dec_TBCD(imsi_hex2oct(imsi)), msisdn := msisdn, rat_type := rat_type, apn := apn, @@ -223,364 +220,12 @@ runs on SMF_Session_CT { g_pars := valueof(pars);
- if (DIAMETER_PROC[DIA_Gx].checkstate("Connected")) { - f_diameter_expect_imsi(g_pars.imsi, idx := DIA_Gx); - } + f_handler_init_4G(); + f_handler_init_5G();
- if (DIAMETER_PROC[DIA_Gy].checkstate("Connected")) { - f_diameter_expect_imsi(g_pars.imsi, idx := DIA_Gy); - } - - if (DIAMETER_PROC[DIA_S6b].checkstate("Connected")) { - f_diameter_expect_imsi(g_pars.imsi, idx := DIA_S6b); - } - - /* allocate + register TEI{C,D} on local side */ - g_pars.teic_local := f_gtp2_allocate_teic(); - g_pars.bearer.teid_local := f_gtp1u_allocate_teid(); fn.apply(); }
-/* S6b emulation (AAA-Server) */ -private altstep as_DIA_S6b_AAR() runs on SMF_Session_CT { - var PDU_DIAMETER rx_dia; - [] DIAMETER[DIA_S6b].receive(tr_DIA_S6b_AAR()) -> value rx_dia { - var template (value) PDU_DIAMETER tx_dia; - tx_dia := f_ts_DIA_S6b_AAA(rx_dia, - "aaa." & mp_diam_realm, - mp_diam_realm, - mp_diam_realm); - DIAMETER[DIA_S6b].send(tx_dia); - setverdict(pass); - } - [] DIAMETER[DIA_S6b].receive(PDU_DIAMETER:?) -> value rx_dia { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - log2str("Received unexpected DIAMETER ", rx_dia)); - } -} - -/* Gx emulation (PCRF)*/ -altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on SMF_Session_CT { - var PDU_DIAMETER rx_dia; - [] DIAMETER[DIA_Gx].receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia { - var template (value) PDU_DIAMETER tx_dia := f_ts_DIA_Gx_CCA(rx_dia); - DIAMETER[DIA_Gx].send(tx_dia); - } - [] DIAMETER[DIA_Gx].receive(PDU_DIAMETER:?) -> value rx_dia { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - log2str("Received unexpected DIAMETER ", rx_dia)); - } -} - -/* Gy emulation (OCS) */ -private function f_tr_DIA_Gy_CCR_sess(DCC_NONE_CC_Request_Type req_type) -runs on SMF_Session_CT return template (present) PDU_DIAMETER -{ - var octetstring imsi := char2oct(f_dec_TBCD(imsi_hex2oct(g_pars.imsi))); - var octetstring rat_type := int2oct(enum2int(g_pars.rat_type), 1); - var OCT1 nsapi := int2oct(g_pars.bearer.ebi, 1); - var OCT4 charging_char := char2oct(oct2str('0000'O)); // f_s5s8_create_session() uses hardcoded chg_car := '0000'O - var template (present) octetstring msisdn := ?; - var charstring smf_origin_host := "smf." & mp_diam_realm; - var octetstring sgsn_addr := f_inet_addr(mp_pcrf_local_ip); - var octetstring ggsn_addr := f_inet_addr(mp_smf_hostname); - - return DIAMETER_ts32_299_Templates.f_tr_DIA_Gy_CCR(req_type, - imsi, - msisdn, - rat_type, - nsapi, - charging_char, - smf_origin_host, - mp_diam_realm, - sgsn_addr, - ggsn_addr); - -} - -altstep as_DIA_Gy_CCR(DCC_NONE_CC_Request_Type req_type) -runs on SMF_Session_CT { - [] DIAMETER[DIA_Gy].receive(f_tr_DIA_Gy_CCR_sess(req_type := req_type)) -> value g_rx_gy { - var template (value) PDU_DIAMETER tx_dia; - var template (omit) integer validity_time := omit; - if (g_pars.gy.validity_time > 0) { - validity_time := g_pars.gy.validity_time; - } - tx_dia := DIAMETER_ts32_299_Templates.f_ts_DIA_Gy_CCA(g_rx_gy, g_pars.gy.cca_res_code, validity_time); - DIAMETER[DIA_Gy].send(tx_dia); - } - [] DIAMETER[DIA_Gy].receive(PDU_DIAMETER:?) -> value g_rx_gy { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - log2str("Received unexpected DIAMETER Gy", g_rx_gy)); - } -} - -/* GTPv2C */ -private function is_s2b_iface() runs on SMF_Session_CT return boolean { - return (g_pars.rat_type == GTP2C_RAT_WLAN or g_pars.rat_type == GTP2C_RAT_Virtual); -} - -private function f_perform_ipv6_slaac() runs on SMF_Session_CT -{ - //var UECUPS_IPv6SLAACInd ipv6slaac_ind; - //var template (value) UECUPS_IPv6SLAAC ipv6slaac; - //ipv6slaac := ts_UECUPS_IPv6SLAAC( - // local_gtp_ep := ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u)), - // rx_teid := oct2int(g_pars.bearer.teid_local) - //); - //f_gtp1u_ipv6_slaac(ipv6slaac); - //GTP1U[0].receive(UECUPS_IPv6SLAACInd:?) -> value ipv6slaac_ind; - //log("5GC assigned IPv6 global prefix: ", ipv6slaac_ind.ipv6_prefix, " -> ", f_inet6_ntoa(ipv6slaac_ind.ipv6_prefix & '0000000000000000'O)); - - ///* Use the first global IPv6 address in the IPv6 prefix picked by osmo-uecups: */ - //g_ip6_addr := ipv6slaac_ind.ipv6_user_addr; - //log("Using IPv6 global address: ", g_ip6_addr); -} - -/* process one to-be-created bearer context */ -private function process_bctx_create(BearerContextGrouped bctx) runs on SMF_Session_CT -{ - g_pars.bearer.ebi := bctx.bearerContextIEs.ePS_Bearer_ID.ePS_Bearer_ID_Value; - /* FIXME: Cause */ - - var integer exp_fteid_if_type; - var BIT4 exp_fteid_instance; - if (is_s2b_iface()) { - exp_fteid_if_type := 33; - exp_fteid_instance := '0100'B; - } else { - exp_fteid_if_type := 5; - exp_fteid_instance := '0010'B; - } - - /* find F-TEID of the P-GW U side */ - var FullyQualifiedTEID rx_fteid; - rx_fteid := valueof(f_GTP2C_find_teid(bctx.bearerContextIEs.fullyQualifiedTEID, - exp_fteid_if_type, exp_fteid_instance)); - g_pars.bearer.teid_remote := rx_fteid.tEID_GRE_Key; - if (rx_fteid.v4_Flag == '1'B) { - g_gtpu4_remote := rx_fteid.iPv4_Address; - } - if (rx_fteid.v6_Flag == '1'B) { - g_gtpu6_remote := rx_fteid.iPv6_Address; - } - - if (g_pars.pdn_type == GTP2C_PDN_IPv6 or - g_pars.pdn_type == GTP2C_PDN_IPv4v6) { - f_perform_ipv6_slaac(); - } -} - -/* create a session on the SMF */ -private function f_create_session(template (value) FullyQualifiedTEID fteid_c_ie, - template (value) FullyQualifiedTEID fteid_u_ie, - template (omit) UserLocationInfo uli_ie := omit, - template (omit) APCO apco := omit, - template APCO exp_apco := *) runs on SMF_Session_CT { - var PDU_GTPCv2 rx; - - /* Defaults used for s5/s8: */ - var boolean do_s6b := false; - var template APN_Restriction apn_restriction := ?; - /* Change behavior when on S2b: */ - if (is_s2b_iface()) { - do_s6b := true; - apn_restriction := omit; - } - - var template (value) PDU_GTPCv2 g2c := - ts_GTP2C_CreateSessionReq(imsi := g_pars.imsi, - msisdn := g_pars.msisdn, - rat_type := enum2int(g_pars.rat_type), - sender_fteid := fteid_c_ie, - apn := f_enc_dns_hostname(g_pars.apn), - pdn_type := int2bit(enum2int(g_pars.pdn_type), 3), - teid_list := { fteid_u_ie }, - chg_car := '0000'O, - bearer_id := g_pars.bearer.ebi, - uli := uli_ie, - apco := apco); - g2c.gtpcv2_pdu.createSessionRequest.servingNetwork := ts_GTP2C_ServingNetwork('001'H, '01F'H); - - /////////// START MUTUAL EXCLUSION ZONE //////////// - /* This code block cannot be executed by more than one component at a time because - * the RANAP RAB Ass Request triggers the IUT to send PFCP Session Establishment - * Request PDU(s), which needs to be routed to the respective ConnHdlr component (us). - * As per 3GPP TS 29.244, section 7.2.2.4.2, these PFCP PDUs shall all have SEID=0, - * so that the PFCPEM component cannot route them unambiguously. This is why we - * need to ensure that only one ConnHdlr is triggering PFCP session establishment - * at the given moment of time. */ - f_Mutex_lock(__BFILE__, __LINE__); - /* Subscribe for PFCP Session Establishment Request PDU(s), which are - * expected to have SEID set to 0, as per 3GPP TS 29.244, section 7.2.2.4.2. */ - f_PFCPEM_subscribe_seid(c_SEID0); - - GTP2.send(g2c); - if (do_s6b and DIAMETER[DIA_S6b].checkstate("Connected")) { - as_DIA_S6b_AAR(); - } - if (DIAMETER[DIA_Gx].checkstate("Connected")) { - as_DIA_Gx_CCR(INITIAL_REQUEST); - } - /* FIXME: When on S2b interface, SMF is not using the Gy interface, unknown reason. */ - if (DIAMETER[DIA_Gy].checkstate("Connected")) { - as_DIA_Gy_CCR(INITIAL_REQUEST); - } - - /* Expect PFCP Session Establishment Request. */ - as_pfcp_sess_est_req(); - /* Ask PFCPEM to route PDUs with to be indicated F-SEID to us. */ - f_PFCPEM_subscribe_seid(g_pars.pfcp_pars.local_f_seid.seid); - /* We're done establishing PFCP sessions, so at this point we no longer expect to - * receive Session Establishment Request PDUs with SEID=0. Unregister and unlock - * the mutex, enabling other components to establish PFCP sessions after us. */ - f_PFCPEM_unsubscribe_seid(c_SEID0); - f_Mutex_unlock(__BFILE__, __LINE__); - /////////// END MUTUAL EXCLUSION ZONE //////////// - - alt { - [] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid := g_pars.teic_local, - cause := Request_accepted, - apn_restriction := apn_restriction, - exp_apco := exp_apco)) -> value rx { - /* extract TEIDs */ - var CreateSessionResponse resp := rx.gtpcv2_pdu.createSessionResponse; - g_pars.teic_remote := resp.fullyQualifiedTEID[0].tEID_GRE_Key; - - /* extract allocated address[es] */ - var PDN_Address_and_Prefix paa := resp.pDN_AddressAllocation.pDN_Address_and_Prefix; - if (ischosen(paa.iPv4_Address)) { - g_ip4_addr := paa.iPv4_Address; - log("SMF assigned UE IPv4 address: ", f_inet_ntoa(g_ip4_addr)); - } else if (ischosen(paa.iPv6_Address)) { - if (paa.iPv6_Address.prefixLength != 64) { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - log2str("Got IPv6 Prefix Length ", - paa.iPv6_Address.prefixLength, " vs exp 64")); - } - g_ip6_interface_id := substr(paa.iPv6_Address.iPv6_Address, 8, 8); - log("SMF assigned IPv6 Interface Id: ", g_ip6_interface_id); - g_ip6_addr := 'FE80000000000000'O & g_ip6_interface_id; - log("SMF assigned IPv6 link-local Address: ", f_inet6_ntoa(g_ip6_addr)); - } else if (ischosen(paa.iPv4_IPv6)) { - if (paa.iPv4_IPv6.prefixLength != 64) { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - log2str("Got IPv6 Prefix Length ", - paa.iPv4_IPv6.prefixLength, " vs exp 64")); - } - g_ip4_addr := paa.iPv4_IPv6.iPv4_Address; - log("SMF assigned UE IPv4 address: ", f_inet_ntoa(g_ip4_addr)); - g_ip6_interface_id := substr(paa.iPv4_IPv6.iPv6_Address, 8, 8); - log("SMF assigned IPv6 Interface Id: ", g_ip6_interface_id); - g_ip6_addr := 'FE80000000000000'O & g_ip6_interface_id; - log("SMF assigned IPv6 link-local Address: ", f_inet6_ntoa(g_ip6_addr)); - } - var integer i; - for (i := 0; i < lengthof(resp.bearerContextGrouped); i := i+1) { - var BearerContextGrouped bctx := resp.bearerContextGrouped[i]; - select (bctx.instance) { - case ('0000'B) { // created - process_bctx_create(bctx); - } - case ('0001'B) { // removed - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - "We don't expect removed bearer contexts yet"); - } - } - } - } - [] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_pars.teic_local, cause:=?)) -> value rx { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - log2str("Unexpected CreateSessionResp(cause=", - rx.gtpcv2_pdu.createSessionResponse.cause.causeValue, ")")); - } - [] GTP2.receive { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - "Unexpected GTPv2 while waiting for CreateSessionResp"); - } - } - -} - -/* create a session on the SMF on a S5/S8 interface (from SGW )*/ -function f_s5s8_create_session() runs on SMF_Session_CT { - var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie; - var template (value) UserLocationInfo uli_ie; - - fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0, - f_inet_addr(mp_local_hostname_c), omit); - fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPU, g_pars.bearer.teid_local, 2, - f_inet_addr(mp_local_hostname_u), omit); - - - /* open5gs up to 1.2.3 won't accept it without ULI, despite not mandatory */ - var template (value) TAI tai := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0001'O }; - var template (value) ECGI ecgi := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0'H, 23 }; - uli_ie := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi); - - f_create_session(fteid_c_ie, fteid_u_ie, uli_ie); - -} - -/* create a session on the SMF on a S2b interface (from ePDG)*/ -function f_s2b_create_session(template (omit) APCO apco := omit, - template APCO exp_apco := *) runs on SMF_Session_CT { - var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie; - var template (value) UserLocationInfo uli_ie; - - fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S2b_ePDG_GTPC, g_pars.teic_local, 0, - f_inet_addr(mp_local_hostname_c), omit); - fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S2bU_ePDG_GTPU, g_pars.bearer.teid_local, 5, - f_inet_addr(mp_local_hostname_u), omit); - - var template (value) TAI tai := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0001'O }; - var template (value) ECGI ecgi := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0'H, 23 }; - uli_ie := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi); - - f_create_session(fteid_c_ie, fteid_u_ie, uli_ie := uli_ie, apco := apco, exp_apco := exp_apco); - -} - -/* delete the session from the SMF */ -function f_delete_session(template (omit) GTP2C_Cause tx_cause := omit, - template (present) GTP2C_Cause exp_cause, - boolean expect_pfcp := true, - boolean expect_diameter := true) runs on SMF_Session_CT { - var template (value) FullyQualifiedTEID fteid_c_ie - fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0, - f_inet_addr(mp_local_hostname_c), omit); - var template PDU_GTPCv2 g2c := - ts_GTP2C_DeleteSessionReq(d_teid := g_pars.teic_remote, cause := tx_cause, - sender_fteid := fteid_c_ie, - teid_list := {}, bearer_id := g_pars.bearer.ebi); - - GTP2.send(g2c); - - if (expect_pfcp) { - as_pfcp_sess_del_req(); - } - - if (DIAMETER[DIA_Gx].checkstate("Connected") and expect_diameter) { - as_DIA_Gx_CCR(TERMINATION_REQUEST); - } - if (DIAMETER[DIA_Gy].checkstate("Connected") and expect_diameter) { - as_DIA_Gy_CCR(TERMINATION_REQUEST); - } - alt { - [] GTP2.receive(tr_GTP2C_DeleteSessionResp(d_teid := g_pars.teic_local, cause := exp_cause)) { - setverdict(pass); - } - [] GTP2.receive(tr_GTP2C_DeleteSessionResp(?, ?)) { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - "Unexpected DeleteSessionResp"); - } - [] GTP2.receive { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, - "Unexpected GTPv2 while waiting for DeleteSessionResp"); - } - } -} - /******* * PFCP *******/ @@ -674,7 +319,7 @@ return tr_PFCP_Session_Est_Req(create_urr := create_urr); }
-private altstep as_pfcp_sess_est_req() +altstep as_pfcp_sess_est_req() runs on SMF_Session_CT { var template (present) PDU_PFCP exp_req := f_Session_tr_PFCP_Session_Est_Req(); var PDU_PFCP req; diff --git a/smf/SMF_Session_CT_4G.ttcn b/smf/SMF_Session_CT_4G.ttcn new file mode 100644 index 0000000..06a7e37 --- /dev/null +++ b/smf/SMF_Session_CT_4G.ttcn @@ -0,0 +1,399 @@ +module SMF_Session_CT_4G { + +import from TCCEncoding_Functions all; + +import from General_Types all; +import from Osmocom_Types all; +import from Native_Functions all; +import from Misc_Helpers all; + +import from GTPv1U_Emulation all; + +import from GTPv2_Types all; +import from GTPv2_Templates all; +import from GTPv2_Emulation all; + +import from DNS_Helpers all; + +import from DIAMETER_Types all; +import from DIAMETER_Templates all; +import from DIAMETER_ts29_212_Templates all; +import from DIAMETER_ts29_272_Templates all; +import from DIAMETER_ts29_273_Templates all; +import from DIAMETER_ts32_299_Templates all; +import from DIAMETER_Emulation all; + +import from HTTP2_Adapter all; +import from HTTP2_Server_Emulation all; + +import from PFCP_Emulation all; +import from Mutex all; + +import from SMF_Session_CT all; +import from SMF_Tests all; + +const integer DIA_Gx := 0; +const integer DIA_Gy := 1; +const integer DIA_S6b := 2; + +function f_handler_init_4G() +runs on SMF_Session_CT { + + if (DIAMETER_PROC[DIA_Gx].checkstate("Connected")) { + f_diameter_expect_imsi(g_pars.imsi, idx := DIA_Gx); + } + + if (DIAMETER_PROC[DIA_Gy].checkstate("Connected")) { + f_diameter_expect_imsi(g_pars.imsi, idx := DIA_Gy); + } + + if (DIAMETER_PROC[DIA_S6b].checkstate("Connected")) { + f_diameter_expect_imsi(g_pars.imsi, idx := DIA_S6b); + } + + /* allocate + register TEI{C,D} on local side */ + g_pars.teic_local := f_gtp2_allocate_teic(); + g_pars.bearer.teid_local := f_gtp1u_allocate_teid(); +} + +/* S6b emulation (AAA-Server) */ +private altstep as_DIA_S6b_AAR() runs on SMF_Session_CT { + var PDU_DIAMETER rx_dia; + [] DIAMETER[DIA_S6b].receive(tr_DIA_S6b_AAR()) -> value rx_dia { + var template (value) PDU_DIAMETER tx_dia; + tx_dia := f_ts_DIA_S6b_AAA(rx_dia, + "aaa." & mp_diam_realm, + mp_diam_realm, + mp_diam_realm); + DIAMETER[DIA_S6b].send(tx_dia); + setverdict(pass); + } + [] DIAMETER[DIA_S6b].receive(PDU_DIAMETER:?) -> value rx_dia { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Received unexpected DIAMETER ", rx_dia)); + } +} + +/* Gx emulation (PCRF)*/ +altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on SMF_Session_CT { + var PDU_DIAMETER rx_dia; + [] DIAMETER[DIA_Gx].receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia { + var template (value) PDU_DIAMETER tx_dia := f_ts_DIA_Gx_CCA(rx_dia); + DIAMETER[DIA_Gx].send(tx_dia); + } + [] DIAMETER[DIA_Gx].receive(PDU_DIAMETER:?) -> value rx_dia { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Received unexpected DIAMETER ", rx_dia)); + } +} + +/* Gy emulation (OCS) */ +private function f_tr_DIA_Gy_CCR_sess(DCC_NONE_CC_Request_Type req_type) +runs on SMF_Session_CT return template (present) PDU_DIAMETER +{ + var octetstring imsi := char2oct(f_dec_TBCD(imsi_hex2oct(g_pars.imsi))); + var octetstring rat_type := int2oct(enum2int(g_pars.rat_type), 1); + var OCT1 nsapi := int2oct(g_pars.bearer.ebi, 1); + var OCT4 charging_char := char2oct(oct2str('0000'O)); // f_s5s8_create_session() uses hardcoded chg_car := '0000'O + var template (present) octetstring msisdn := ?; + var charstring smf_origin_host := "smf." & mp_diam_realm; + var octetstring sgsn_addr := f_inet_addr(mp_pcrf_local_ip); + var octetstring ggsn_addr := f_inet_addr(mp_smf_hostname); + + return DIAMETER_ts32_299_Templates.f_tr_DIA_Gy_CCR(req_type, + imsi, + msisdn, + rat_type, + nsapi, + charging_char, + smf_origin_host, + mp_diam_realm, + sgsn_addr, + ggsn_addr); + +} + +altstep as_DIA_Gy_CCR(DCC_NONE_CC_Request_Type req_type) +runs on SMF_Session_CT { + [] DIAMETER[DIA_Gy].receive(f_tr_DIA_Gy_CCR_sess(req_type := req_type)) -> value g_rx_gy { + var template (value) PDU_DIAMETER tx_dia; + var template (omit) integer validity_time := omit; + if (g_pars.gy.validity_time > 0) { + validity_time := g_pars.gy.validity_time; + } + tx_dia := DIAMETER_ts32_299_Templates.f_ts_DIA_Gy_CCA(g_rx_gy, g_pars.gy.cca_res_code, validity_time); + DIAMETER[DIA_Gy].send(tx_dia); + } + [] DIAMETER[DIA_Gy].receive(PDU_DIAMETER:?) -> value g_rx_gy { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Received unexpected DIAMETER Gy", g_rx_gy)); + } +} + +/* GTPv2C */ +private function is_s2b_iface() runs on SMF_Session_CT return boolean { + return (g_pars.rat_type == GTP2C_RAT_WLAN or g_pars.rat_type == GTP2C_RAT_Virtual); +} + +private function f_perform_ipv6_slaac() runs on SMF_Session_CT +{ + //var UECUPS_IPv6SLAACInd ipv6slaac_ind; + //var template (value) UECUPS_IPv6SLAAC ipv6slaac; + //ipv6slaac := ts_UECUPS_IPv6SLAAC( + // local_gtp_ep := ts_UECUPS_SockAddr(f_inet_addr(mp_local_hostname_u)), + // rx_teid := oct2int(g_pars.bearer.teid_local) + //); + //f_gtp1u_ipv6_slaac(ipv6slaac); + //GTP1U[0].receive(UECUPS_IPv6SLAACInd:?) -> value ipv6slaac_ind; + //log("5GC assigned IPv6 global prefix: ", ipv6slaac_ind.ipv6_prefix, " -> ", f_inet6_ntoa(ipv6slaac_ind.ipv6_prefix & '0000000000000000'O)); + + ///* Use the first global IPv6 address in the IPv6 prefix picked by osmo-uecups: */ + //g_ip6_addr := ipv6slaac_ind.ipv6_user_addr; + //log("Using IPv6 global address: ", g_ip6_addr); +} + +/* process one to-be-created bearer context */ +private function process_bctx_create(BearerContextGrouped bctx) runs on SMF_Session_CT +{ + g_pars.bearer.ebi := bctx.bearerContextIEs.ePS_Bearer_ID.ePS_Bearer_ID_Value; + /* FIXME: Cause */ + + var integer exp_fteid_if_type; + var BIT4 exp_fteid_instance; + if (is_s2b_iface()) { + exp_fteid_if_type := 33; + exp_fteid_instance := '0100'B; + } else { + exp_fteid_if_type := 5; + exp_fteid_instance := '0010'B; + } + + /* find F-TEID of the P-GW U side */ + var FullyQualifiedTEID rx_fteid; + rx_fteid := valueof(f_GTP2C_find_teid(bctx.bearerContextIEs.fullyQualifiedTEID, + exp_fteid_if_type, exp_fteid_instance)); + g_pars.bearer.teid_remote := rx_fteid.tEID_GRE_Key; + if (rx_fteid.v4_Flag == '1'B) { + g_gtpu4_remote := rx_fteid.iPv4_Address; + } + if (rx_fteid.v6_Flag == '1'B) { + g_gtpu6_remote := rx_fteid.iPv6_Address; + } + + if (g_pars.pdn_type == GTP2C_PDN_IPv6 or + g_pars.pdn_type == GTP2C_PDN_IPv4v6) { + f_perform_ipv6_slaac(); + } +} + +/* create a session on the SMF */ +private function f_create_session(template (value) FullyQualifiedTEID fteid_c_ie, + template (value) FullyQualifiedTEID fteid_u_ie, + template (omit) UserLocationInfo uli_ie := omit, + template (omit) APCO apco := omit, + template APCO exp_apco := *) runs on SMF_Session_CT { + var PDU_GTPCv2 rx; + + /* Defaults used for s5/s8: */ + var boolean do_s6b := false; + var template APN_Restriction apn_restriction := ?; + /* Change behavior when on S2b: */ + if (is_s2b_iface()) { + do_s6b := true; + apn_restriction := omit; + } + + var template (value) PDU_GTPCv2 g2c := + ts_GTP2C_CreateSessionReq(imsi := g_pars.imsi, + msisdn := g_pars.msisdn, + rat_type := enum2int(g_pars.rat_type), + sender_fteid := fteid_c_ie, + apn := f_enc_dns_hostname(g_pars.apn), + pdn_type := int2bit(enum2int(g_pars.pdn_type), 3), + teid_list := { fteid_u_ie }, + chg_car := '0000'O, + bearer_id := g_pars.bearer.ebi, + uli := uli_ie, + apco := apco); + g2c.gtpcv2_pdu.createSessionRequest.servingNetwork := ts_GTP2C_ServingNetwork('001'H, '01F'H); + + /////////// START MUTUAL EXCLUSION ZONE //////////// + /* This code block cannot be executed by more than one component at a time because + * the RANAP RAB Ass Request triggers the IUT to send PFCP Session Establishment + * Request PDU(s), which needs to be routed to the respective ConnHdlr component (us). + * As per 3GPP TS 29.244, section 7.2.2.4.2, these PFCP PDUs shall all have SEID=0, + * so that the PFCPEM component cannot route them unambiguously. This is why we + * need to ensure that only one ConnHdlr is triggering PFCP session establishment + * at the given moment of time. */ + f_Mutex_lock(__BFILE__, __LINE__); + /* Subscribe for PFCP Session Establishment Request PDU(s), which are + * expected to have SEID set to 0, as per 3GPP TS 29.244, section 7.2.2.4.2. */ + f_PFCPEM_subscribe_seid(c_SEID0); + + GTP2.send(g2c); + if (do_s6b and DIAMETER[DIA_S6b].checkstate("Connected")) { + as_DIA_S6b_AAR(); + } + if (DIAMETER[DIA_Gx].checkstate("Connected")) { + as_DIA_Gx_CCR(INITIAL_REQUEST); + } + /* FIXME: When on S2b interface, SMF is not using the Gy interface, unknown reason. */ + if (DIAMETER[DIA_Gy].checkstate("Connected")) { + as_DIA_Gy_CCR(INITIAL_REQUEST); + } + + /* Expect PFCP Session Establishment Request. */ + as_pfcp_sess_est_req(); + /* Ask PFCPEM to route PDUs with to be indicated F-SEID to us. */ + f_PFCPEM_subscribe_seid(g_pars.pfcp_pars.local_f_seid.seid); + /* We're done establishing PFCP sessions, so at this point we no longer expect to + * receive Session Establishment Request PDUs with SEID=0. Unregister and unlock + * the mutex, enabling other components to establish PFCP sessions after us. */ + f_PFCPEM_unsubscribe_seid(c_SEID0); + f_Mutex_unlock(__BFILE__, __LINE__); + /////////// END MUTUAL EXCLUSION ZONE //////////// + + alt { + [] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid := g_pars.teic_local, + cause := Request_accepted, + apn_restriction := apn_restriction, + exp_apco := exp_apco)) -> value rx { + /* extract TEIDs */ + var CreateSessionResponse resp := rx.gtpcv2_pdu.createSessionResponse; + g_pars.teic_remote := resp.fullyQualifiedTEID[0].tEID_GRE_Key; + + /* extract allocated address[es] */ + var PDN_Address_and_Prefix paa := resp.pDN_AddressAllocation.pDN_Address_and_Prefix; + if (ischosen(paa.iPv4_Address)) { + g_ip4_addr := paa.iPv4_Address; + log("SMF assigned UE IPv4 address: ", f_inet_ntoa(g_ip4_addr)); + } else if (ischosen(paa.iPv6_Address)) { + if (paa.iPv6_Address.prefixLength != 64) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Got IPv6 Prefix Length ", + paa.iPv6_Address.prefixLength, " vs exp 64")); + } + g_ip6_interface_id := substr(paa.iPv6_Address.iPv6_Address, 8, 8); + log("SMF assigned IPv6 Interface Id: ", g_ip6_interface_id); + g_ip6_addr := 'FE80000000000000'O & g_ip6_interface_id; + log("SMF assigned IPv6 link-local Address: ", f_inet6_ntoa(g_ip6_addr)); + } else if (ischosen(paa.iPv4_IPv6)) { + if (paa.iPv4_IPv6.prefixLength != 64) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Got IPv6 Prefix Length ", + paa.iPv4_IPv6.prefixLength, " vs exp 64")); + } + g_ip4_addr := paa.iPv4_IPv6.iPv4_Address; + log("SMF assigned UE IPv4 address: ", f_inet_ntoa(g_ip4_addr)); + g_ip6_interface_id := substr(paa.iPv4_IPv6.iPv6_Address, 8, 8); + log("SMF assigned IPv6 Interface Id: ", g_ip6_interface_id); + g_ip6_addr := 'FE80000000000000'O & g_ip6_interface_id; + log("SMF assigned IPv6 link-local Address: ", f_inet6_ntoa(g_ip6_addr)); + } + var integer i; + for (i := 0; i < lengthof(resp.bearerContextGrouped); i := i+1) { + var BearerContextGrouped bctx := resp.bearerContextGrouped[i]; + select (bctx.instance) { + case ('0000'B) { // created + process_bctx_create(bctx); + } + case ('0001'B) { // removed + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + "We don't expect removed bearer contexts yet"); + } + } + } + } + [] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_pars.teic_local, cause:=?)) -> value rx { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Unexpected CreateSessionResp(cause=", + rx.gtpcv2_pdu.createSessionResponse.cause.causeValue, ")")); + } + [] GTP2.receive { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + "Unexpected GTPv2 while waiting for CreateSessionResp"); + } + } + +} + +/* create a session on the SMF on a S5/S8 interface (from SGW )*/ +function f_s5s8_create_session() runs on SMF_Session_CT { + var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie; + var template (value) UserLocationInfo uli_ie; + + fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0, + f_inet_addr(mp_local_hostname_c), omit); + fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPU, g_pars.bearer.teid_local, 2, + f_inet_addr(mp_local_hostname_u), omit); + + + /* open5gs up to 1.2.3 won't accept it without ULI, despite not mandatory */ + var template (value) TAI tai := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0001'O }; + var template (value) ECGI ecgi := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0'H, 23 }; + uli_ie := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi); + + f_create_session(fteid_c_ie, fteid_u_ie, uli_ie); + +} + +/* create a session on the SMF on a S2b interface (from ePDG)*/ +function f_s2b_create_session(template (omit) APCO apco := omit, + template APCO exp_apco := *) runs on SMF_Session_CT { + var template (value) FullyQualifiedTEID fteid_c_ie, fteid_u_ie; + var template (value) UserLocationInfo uli_ie; + + fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S2b_ePDG_GTPC, g_pars.teic_local, 0, + f_inet_addr(mp_local_hostname_c), omit); + fteid_u_ie := ts_GTP2C_FTEID(FTEID_IF_S2bU_ePDG_GTPU, g_pars.bearer.teid_local, 5, + f_inet_addr(mp_local_hostname_u), omit); + + var template (value) TAI tai := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0001'O }; + var template (value) ECGI ecgi := { '0'H, '0'H, '1'H, 'F'H, '0'H, '1'H, '0'H, 23 }; + uli_ie := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi); + + f_create_session(fteid_c_ie, fteid_u_ie, uli_ie := uli_ie, apco := apco, exp_apco := exp_apco); + +} + +/* delete the session from the SMF */ +function f_delete_session(template (omit) GTP2C_Cause tx_cause := omit, + template (present) GTP2C_Cause exp_cause, + boolean expect_pfcp := true, + boolean expect_diameter := true) runs on SMF_Session_CT { + var template (value) FullyQualifiedTEID fteid_c_ie + fteid_c_ie := ts_GTP2C_FTEID(FTEID_IF_S5S8_SGW_GTPC, g_pars.teic_local, 0, + f_inet_addr(mp_local_hostname_c), omit); + var template PDU_GTPCv2 g2c := + ts_GTP2C_DeleteSessionReq(d_teid := g_pars.teic_remote, cause := tx_cause, + sender_fteid := fteid_c_ie, + teid_list := {}, bearer_id := g_pars.bearer.ebi); + + GTP2.send(g2c); + + if (expect_pfcp) { + as_pfcp_sess_del_req(); + } + + if (DIAMETER[DIA_Gx].checkstate("Connected") and expect_diameter) { + as_DIA_Gx_CCR(TERMINATION_REQUEST); + } + if (DIAMETER[DIA_Gy].checkstate("Connected") and expect_diameter) { + as_DIA_Gy_CCR(TERMINATION_REQUEST); + } + alt { + [] GTP2.receive(tr_GTP2C_DeleteSessionResp(d_teid := g_pars.teic_local, cause := exp_cause)) { + setverdict(pass); + } + [] GTP2.receive(tr_GTP2C_DeleteSessionResp(?, ?)) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + "Unexpected DeleteSessionResp"); + } + [] GTP2.receive { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + "Unexpected GTPv2 while waiting for DeleteSessionResp"); + } + } +} + +} diff --git a/smf/SMF_Session_CT_5G.ttcn b/smf/SMF_Session_CT_5G.ttcn new file mode 100644 index 0000000..71047a7 --- /dev/null +++ b/smf/SMF_Session_CT_5G.ttcn @@ -0,0 +1,441 @@ +module SMF_Session_CT_5G { + +import from General_Types all; +import from Osmocom_Types all; +import from Native_Functions all; +import from Misc_Helpers all; + +import from HTTP2_Types all; +import from HTTP2_Templates all; +import from HTTP2_Functions all; +import from HTTP2_Adapter all; +import from HTTP2_Server_Emulation all; + +import from TS29518_Namf_Communication all; +import from TS29503_Nudm_SDM all; +import from TS29502_Nsmf_PDUSession all; +import from TS29512_Npcf_SMPolicyControl all; + +import from TS29518_Namf_Communication_Templates all; +import from TS29503_Nudm_SDM_Templates all; +import from TS29502_Nsmf_PDUSession_Templates all; +import from TS29512_Npcf_SMPolicyControl_Templates all; + +import from PFCP_Emulation all; +import from Mutex all; + +import from SMF_Session_CT all; +import from SMF_Tests all; + +/* Index in SMF_Session_CT inherited HTTP2_ConnHdlr ports HTTP2_CONN[] and HTTP2_CONN_PROC[] */ +const integer HTTP2_CONN_SCP := 0; + +function f_handler_init_5G() +runs on SMF_Session_CT { + /* Create SCP HTTP2 sever, where IUT will send all SBI requests: */ + f_http2_server_emu_register(); +} + +/******************************************** + * N11 Nsmf (SBI): Requests towards IUT SMF + ********************************************/ + +function f_n11_init() runs on SMF_Session_CT { + f_http2_adapter_init(); + f_http2_adapter_connect(mp_smf_hostname, mp_smf_sbi_port, mp_amf_local_ip, -1); + + var template (value) HTTP2_Setting_list settings := { + ts_HTTP2_Setting_ENABLE_PUSH(0), + ts_HTTP2_Setting_INITIAL_WINDOW_SIZE(4194304), + ts_HTTP2_Setting_MAX_HEADER_LIST_SIZE(10485760) + } + f_http2_adapter_send(ts_HTTP2_Frame_Settings(settings := settings)); + + f_http2_adapter_send(ts_HTTP2_Frame_Window_Update(0, 1073741824)); +} + +function f_http2_header_block_encode(HTTP2_header_block hb) return octetstring +{ + var HTTP2_comp_context ctx := HTTP2_comp_context_init(); + var integer rc; + var octetstring data := ''O; + + rc := HTTP2_comp_context_encode(ctx, hb, data); + if (rc != 0) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("HTTP2_comp_context_encode returned ", rc)); + } + HTTP2_comp_context_free(ctx); + return data; +} + +function f_http2_encode_body_multipart_json_5gnas(octetstring json_encoded, + octetstring nas_ecnoded, + charstring boundary := "=-0EVVjxcWWFYNd1JXh1OQEg==") return octetstring +{ + var charstring boundary_ext := "\r\n--" & boundary & "\r\n"; + var octetstring boundary_enc := char2oct(boundary_ext); + + return boundary_enc & + char2oct("Content-Type: application/json\r\n\r\n") & + json_encoded & + boundary_enc & + char2oct("Content-Id: 5gnas-sm\r\n") & + char2oct("Content-Type: application/vnd.3gpp.5gnas\r\n\r\n") & + nas_ecnoded & + boundary_enc; +} + +/* Nsmf_PDUSession_CreateSMContext Request/response + * 3GPP TS 23.502 Figure 4.3.2.2.1-1 + * 3GPP TS 29.502 6.1.3.2 */ +function f_n11_create_session() +runs on SMF_Session_CT { + var octetstring hdr_enc; + var template (value) HTTP2_pseudo_headers pseudo_hdr; + var template (value) HTTP2_header_list hdr_li; + var template (value) HTTP2_header_block hb; + var template (value) octetstring body; + var template (value) TS29502_Nsmf_PDUSession.PlmnId plmn_id := TS29502_Nsmf_PDUSession_Templates.ts_PlmnId("001", "001"); + var template (value) TS29502_Nsmf_PDUSession.PlmnIdNid plmn_id_nid := TS29502_Nsmf_PDUSession_Templates.ts_PlmnIdNid(plmn_id.mcc, plmn_id.mnc); + var integer pduSessionId := 1; + + var template (value) SmContextCreateData sm_contexts; + var octetstring sm_contexts_enc; + sm_contexts := ts_SmContextCreateData(supi := "imsi-" & g_pars.imsi_str, + pei := "imeisv-0790219824011594", + pduSessionId := pduSessionId, + dnn := "internet", + sNssai := TS29502_Nsmf_PDUSession_Templates.ts_Snssai(1), + servingNfId := "foobar", + guami := ts_Guami(plmnId := plmn_id_nid, + amfId := "020040"), + servingNetwork := plmn_id_nid, + n1SmMsg := TS29502_Nsmf_PDUSession_Templates.ts_RefToBinaryData("5gnas-sm"), + anType := ThreeGPP_ACCESS, + ratType := ts_RatType(NR), + ueLocation := ts_UserLocation(nrLocation := ts_NrLocation(tai := ts_Tai(plmn_id, "000001"), + ncgi := ts_Ncgi(plmn_id, "000000000"))), + smContextStatusUri := f_amf_callback_uri(g_pars.imsi_str, "sm-context-status", pduSessionId)); + sm_contexts_enc := f_enc_SmContextCreateData(valueof(sm_contexts)); + + var charstring boundary := "=-0EVVjxcWWFYNd1JXh1OQEg==" + var octetstring nas_enc := '2e0101c1ffff91a1'O; + body := f_http2_encode_body_multipart_json_5gnas(sm_contexts_enc, nas_enc, boundary); + + pseudo_hdr := ts_HTTP2_pseudo_headers("POST", + "http", + mp_smf_hostname & ":" & int2str(mp_smf_sbi_port), + "/nsmf-pdusession/v1/sm-contexts"); + hdr_li := { + ts_HTTP2_Hdr_content_type("multipart/related; boundary="" & boundary & """), + ts_HTTP2_Hdr_accept("application/json,application/vnd.3gpp.ngap,application/problem+json"), + ts_HTTP2_Hdr_user_agent("ttcn3-amf"), + ts_HTTP2_Hdr_content_length(int2str(lengthof(body))), + ts_HTTP2_Hdr_accept_encoding("gzip") + }; + hb := ts_HTTP2_header_block(pseudo_hdr, hdr_li); + hdr_enc := f_http2_header_block_encode(valueof(hb)); + f_http2_adapter_send(ts_HTTP2_Frame_Header(3, + end_stream_flag := false, + end_header_flag := true, + header_block_fragment := hdr_enc + )); + + + /////////// START MUTUAL EXCLUSION ZONE //////////// + /* This code block cannot be executed by more than one component at a time because + * the RANAP RAB Ass Request triggers the IUT to send PFCP Session Establishment + * Request PDU(s), which needs to be routed to the respective ConnHdlr component (us). + * As per 3GPP TS 29.244, section 7.2.2.4.2, these PFCP PDUs shall all have SEID=0, + * so that the PFCPEM component cannot route them unambiguously. This is why we + * need to ensure that only one ConnHdlr is triggering PFCP session establishment + * at the given moment of time. */ + f_Mutex_lock(__BFILE__, __LINE__); + /* Subscribe for PFCP Session Establishment Request PDU(s), which are + * expected to have SEID set to 0, as per 3GPP TS 29.244, section 7.2.2.4.2. */ + f_PFCPEM_subscribe_seid(c_SEID0); + + f_http2_adapter_send(ts_HTTP2_Frame_Data(3, + end_stream_flag := true, + data := body)); + + /* Expect UDM to receive GET sm-data: */ + as_nudm_sdm_get_sm_data(); + /* Expect UDM to receive POST sdm-subscriptions: */ + as_nudm_sdm_post_sdm_subscriptions(); + /* Expect PCF to receive POST sm-policies: */ + as_npcf_smpolicycontrol_post_sm_policies(); + + /* Expect PFCP Session Establishment Request. */ + as_pfcp_sess_est_req(); + /* Ask PFCPEM to route PDUs with to be indicated F-SEID to us. */ + f_PFCPEM_subscribe_seid(g_pars.pfcp_pars.local_f_seid.seid); + /* We're done establishing PFCP sessions, so at this point we no longer expect to + * receive Session Establishment Request PDUs with SEID=0. Unregister and unlock + * the mutex, enabling other components to establish PFCP sessions after us. */ + f_PFCPEM_unsubscribe_seid(c_SEID0); + f_Mutex_unlock(__BFILE__, __LINE__); + /////////// END MUTUAL EXCLUSION ZONE //////////// + + as_namf_comm_post_n1n2_messages(); + setverdict(pass); + f_sleep(3.0); +} + +function f_n11_delete_session() +runs on SMF_Session_CT { + log("f_n11_delete_session(): TODO"); +} + +/************************************** + * N11 Namf (SBI): Emulated AMF + **************************************/ + +const charstring Namf_Communication_API_PREFIX := "/namf-comm/v1" + +function f_namf_comm_uri_imsi_prefix(charstring imsi) +return charstring { + return Namf_Communication_API_PREFIX & "/ue-contexts" & "/imsi-" & imsi +} + +/* 3GPP TS 29.518: + * 6.1.3.5 Resource: N1N2 Messages Collection */ +function f_tr_Namf_Communication_post_n1n2_messages() +runs on SMF_Session_CT return template (present) HTTP2_Msg { + var template (present) HTTP2_Msg http2_msg; + var template (present) HTTP2_header_block hb; + var template (present) HTTP2_pseudo_headers pseudo_headers; + var template HTTP2_header_list headers := *; + + pseudo_headers := tr_HTTP2_pseudo_headers(method := "POST", + path := f_namf_comm_uri_imsi_prefix(g_pars.imsi_str) & "/n1-n2-messages"); + hb := tr_HTTP2_header_block(pseudo_headers, headers); + http2_msg := tr_HTTP2_Msg(?, ?, + hb := hb, + body := tr_HTTP2_Data_frame(data := ? /* multipart */)); + return http2_msg; +} + +/* 5.2.2.3.1 N1N2MessageTransfer */ +private altstep as_namf_comm_post_n1n2_messages() +runs on SMF_Session_CT { + var HTTP2_Msg http2_rx; + [] HTTP2_CONN[HTTP2_CONN_SCP].receive(f_tr_Namf_Communication_post_n1n2_messages()) -> value http2_rx { + var N1N2MessageTransferReqData n1n2msg_req; + var template (value) N1N2MessageTransferRspData n1n2msg_rsp; + var template (value) HTTP2_Msg http2_tx; + var octetstring body_enc; + + /* Split http2_rx.body.data into chunks since it is a multipart message: */ + var charstring content_type_val := valueof(f_HTTP2_header_list_find_header(http2_rx.hb.headers, c_HTTP2_HDR_content_type)); + var charstring boundary := f_HTTP2_header_content_type_multipart_val_get_boundary(content_type_val) + var HTTP2_multipart_part_list parts := f_HTTP2_multipart_msg_parse(http2_rx.body.data, boundary); + log("PESPIN: rx http2 multipart! ", parts); + + /* Decode 1st part: SBI json: */ + f_dec_N1N2MessageTransferReqData(parts[0].data, n1n2msg_req); // TODO: check returned integer. + log("PESPIN: N1N2MessageTransferReqData:", n1n2msg_req); + + /* Tx answer: */ + n1n2msg_rsp := ts_N1N2MessageTransferRspData(cause := ts_N1N2MessageTransferCause(N1_N2_TRANSFER_INITIATED)) + body_enc := f_enc_N1N2MessageTransferRspData(valueof(n1n2msg_rsp)); + + http2_tx := ts_HTTP2_Msg_200_OK(http2_rx.conn_id, + http2_rx.stream_id, + headers := { + ts_HTTP2_Hdr_content_type("application/json; charset=utf-8") + }, + body := ts_HTTP2_Data_frame(http2_rx.stream_id, + end_stream_flag := true, + data := body_enc)); + HTTP2_CONN[HTTP2_CONN_SCP].send(http2_tx); + setverdict(pass); + } +} + +/************************************* + * N10 Nudm (SBI): Emulated UDM + *************************************/ + +const charstring Nudm_SDM_API_PREFIX := "/nudm-sdm/v2" + +function f_nudm_sdm_uri_imsi_prefix(charstring imsi) +return charstring { + return Nudm_SDM_API_PREFIX & "/imsi-" & imsi +} + +function f_nudm_sdm_uri_imsi_subscr_prefix(charstring imsi, charstring opcode, integer pduSessionId) +return charstring { + return f_nudm_sdm_uri_imsi_prefix(imsi) & "/" & opcode & "/" & int2str(pduSessionId); +} + +/* 3GPP TS 29.503: + * 5.2.2.2.5 Session Management Subscription Data Retrieval + * 6.1.3.8 Resource: SessionManagementSubscriptionData (Document) */ +function f_tr_Nudm_SDM_get_sm_data() +runs on SMF_Session_CT return template (present) HTTP2_Msg { + var template (present) HTTP2_Msg http2_msg; + var template (present) HTTP2_header_block hb; + var template (present) HTTP2_pseudo_headers pseudo_headers; + var template HTTP2_header_list headers := *; + + pseudo_headers := tr_HTTP2_pseudo_headers(method := "GET", + path := pattern Nudm_SDM_API_PREFIX & "/imsi-" & g_pars.imsi_str & "/sm-data*"); + hb := tr_HTTP2_header_block(pseudo_headers, headers); + http2_msg := tr_HTTP2_Msg(?, ?, hb := hb, body := omit); + return http2_msg; +} + +/* 3GPP TS 29.503 5.2.2.2.5 Session Management Subscription Data Retrieval */ +private altstep as_nudm_sdm_get_sm_data() +runs on SMF_Session_CT { + var HTTP2_Msg http2_rx; + [] HTTP2_CONN[HTTP2_CONN_SCP].receive(f_tr_Nudm_SDM_get_sm_data()) -> value http2_rx { + var template (value) SessionManagementSubscriptionData1 sm_sub_data; + var template (value) DnnConfiguration1 dnn_cfg; + var octetstring body_enc; + var template (value) HTTP2_Msg http2_tx; + + dnn_cfg := ts_DnnConfiguration1(pduSessionTypes := ts_PduSessionTypes1(defaultSessionType := ts_PduSessionType1(IPV4), + allowedSessionTypes := { ts_PduSessionType1(IPV4) }), + sscModes := ts_SscModes1(defaultSscMode := ts_SscMode1(SSC_MODE_1), + allowedSscModes := { ts_SscMode1(SSC_MODE_1), + ts_SscMode1(SSC_MODE_2), + ts_SscMode1(SSC_MODE_3)}), + fivegQosProfile := ts_SubscribedDefaultQos1(fiveqi := 9, + arp := ts_Arp(priorityLevel := ts_ArpPriorityLevel(8), + preemptCap := ts_PreemptionCapability(NOT_PREEMPT), + preemptVuln := ts_PreemptionVulnerability(NOT_PREEMPTABLE)), + priorityLevel := 8), + sessionAmbr := ts_Ambr1(uplink := "1000 Kbps", + downlink := "1000 Kbps") + ); + + sm_sub_data := ts_SessionManagementSubscriptionData1( + singleNssai := TS29503_Nudm_SDM_Templates.ts_Snssai1(1), + dnnConfigurations := {{"internet", dnn_cfg}} + ); + body_enc := f_enc_SmSubsData1(valueof(ts_SmSubsData1({sm_sub_data}))); + + http2_tx := ts_HTTP2_Msg_200_OK(http2_rx.conn_id, + http2_rx.stream_id, + headers := { + ts_HTTP2_Hdr_content_type("application/json; charset=utf-8") + }, + body := ts_HTTP2_Data_frame(http2_rx.stream_id, + end_stream_flag := true, + data := body_enc)); + HTTP2_CONN[HTTP2_CONN_SCP].send(http2_tx); + setverdict(pass); + } +} + + +/* 3GPP TS 29.503: + * 6.1.3.3 Resource: SdmSubscriptions (Collection)*/ +function f_tr_Nudm_SDM_post_sdm_subscriptions() +runs on SMF_Session_CT return template (present) HTTP2_Msg { + var template (present) HTTP2_Msg http2_msg; + var template (present) HTTP2_header_block hb; + var template (present) HTTP2_pseudo_headers pseudo_headers; + var template HTTP2_header_list headers := *; + + pseudo_headers := tr_HTTP2_pseudo_headers(method := "POST", + path := f_nudm_sdm_uri_imsi_prefix(g_pars.imsi_str) & "/sdm-subscriptions"); + hb := tr_HTTP2_header_block(pseudo_headers, headers); + http2_msg := tr_HTTP2_Msg(?, ?, + hb := hb, + body := tr_HTTP2_Data_frame(data := decmatch tr_SdmSubscription1)); + return http2_msg; +} + +/* 3GPP TS 29.503 5.2.2.3.2 Subscription to notifications of data change */ +private altstep as_nudm_sdm_post_sdm_subscriptions() +runs on SMF_Session_CT { + var HTTP2_Msg http2_rx; + [] HTTP2_CONN[HTTP2_CONN_SCP].receive(f_tr_Nudm_SDM_post_sdm_subscriptions()) -> value http2_rx { + var SdmSubscription1 sdm_subscription; + var template (value) HTTP2_Msg http2_tx; + var octetstring body_enc; + + f_dec_SdmSubscription1(http2_rx.body.data, sdm_subscription); // TODO: check returned integer. + + /* Add subscriptionId to received object and transmit it back: */ + sdm_subscription.subscriptionId := "1"; + body_enc := f_enc_SdmSubscription1(sdm_subscription); + + http2_tx := ts_HTTP2_Msg_201_Created(http2_rx.conn_id, + http2_rx.stream_id, + headers := { + ts_HTTP2_Hdr_content_type("application/json; charset=utf-8"), + ts_HTTP2_Hdr_location(f_scp_uri_prefix() & f_nudm_sdm_uri_imsi_subscr_prefix(g_pars.imsi_str, "sdm-subscriptions", 1)) + }, + body := ts_HTTP2_Data_frame(http2_rx.stream_id, + end_stream_flag := true, + data := body_enc)); + HTTP2_CONN[HTTP2_CONN_SCP].send(http2_tx); + setverdict(pass); + } +} + +/************************************* + * N8 NPcf (SBI): Emulated PCF + *************************************/ + +const charstring Npcf_SMPolicyControl_API_PREFIX := "/npcf-smpolicycontrol/v1" + +function f_npcf_smpolicycontrol_uri_imsi_prefix(charstring imsi) +return charstring { + return Npcf_SMPolicyControl_API_PREFIX & "/imsi-" & imsi +} + +/* 3GPP TS 29.512: + * 5.3.2 Resource: SM Policies */ +function f_tr_Npcf_SMPolicyControl_post_sm_policies() +runs on SMF_Session_CT return template (present) HTTP2_Msg { + var template (present) HTTP2_Msg http2_msg; + var template (present) HTTP2_header_block hb; + var template (present) HTTP2_pseudo_headers pseudo_headers; + var template HTTP2_header_list headers := *; + + pseudo_headers := tr_HTTP2_pseudo_headers(method := "POST", + path := Npcf_SMPolicyControl_API_PREFIX & "/sm-policies"); + hb := tr_HTTP2_header_block(pseudo_headers, headers); + http2_msg := tr_HTTP2_Msg(?, ?, + hb := hb, + body := tr_HTTP2_Data_frame(data := decmatch tr_SmPolicyContextData1)); + return http2_msg; +} + +/* 3GPP TS 29.512 4.2.2.2 SM Policy Association establishment */ +private altstep as_npcf_smpolicycontrol_post_sm_policies() +runs on SMF_Session_CT { + var HTTP2_Msg http2_rx; + [] HTTP2_CONN[HTTP2_CONN_SCP].receive(f_tr_Npcf_SMPolicyControl_post_sm_policies()) -> value http2_rx { + var SmPolicyContextData1 smpol_ctx_data; + var template (value) SmPolicyDecision1 smpol_decision; + var template (value) HTTP2_Msg http2_tx; + var octetstring body_enc; + var integer sessRuleId := 1; + + f_dec_SmPolicyContextData1(http2_rx.body.data, smpol_ctx_data); // TODO: check returned integer. + + smpol_decision := ts_SmPolicyDecision1(); + body_enc := f_enc_SmPolicyDecision1(valueof(smpol_decision)); + + http2_tx := ts_HTTP2_Msg_201_Created(http2_rx.conn_id, + http2_rx.stream_id, + headers := { + ts_HTTP2_Hdr_content_type("application/json; charset=utf-8"), + ts_HTTP2_Hdr_location(f_scp_uri_prefix() & Npcf_SMPolicyControl_API_PREFIX & "/sm-policies/imsi-" & g_pars.imsi_str & "-" & int2str(sessRuleId)) + }, + body := ts_HTTP2_Data_frame(http2_rx.stream_id, + end_stream_flag := true, + data := body_enc)); + HTTP2_CONN[HTTP2_CONN_SCP].send(http2_tx); + setverdict(pass); + } +} + +} diff --git a/smf/SMF_Tests.ttcn b/smf/SMF_Tests.ttcn index b452bd9..2becc57 100644 --- a/smf/SMF_Tests.ttcn +++ b/smf/SMF_Tests.ttcn @@ -28,11 +28,19 @@ import from PFCP_Templates all; import from PFCP_CodecPort all;
+import from HTTP2_Types all; +import from HTTP2_Templates all; +import from HTTP2_Adapter all; +import from HTTP2_Server_Emulation all; + import from Mutex all; import from SMF_Session_CT all; +import from SMF_Session_CT_4G all; +import from SMF_Session_CT_5G all;
modulepar { charstring mp_smf_hostname := "127.0.0.4"; + integer mp_smf_sbi_port := 7777; charstring mp_local_hostname_c := "127.0.0.1"; charstring mp_local_hostname_u := "127.0.0.1";
@@ -50,10 +58,17 @@ /* IP address at which we listen for PFCP to emulate a UPF in ttcn3 */ charstring mp_pfcp_ip_local := "127.0.0.7"; charstring mp_pfcp_upf_node_id := "\07osmocom\03org"; + + + /* IP address at which we listen for HTTP2/SBI to emulate a AMF in ttcn3 */ + charstring mp_amf_local_ip := "127.0.0.4"; + charstring mp_scp_local_ip := "127.0.1.10"; + integer mp_scp_local_port := 7777; }
+ /* main component, we typically have one per testcase */ -type component SMF_Test_CT extends GTP2_ConnHdlr, PFCP_ConnHdlr { +type component SMF_Test_CT extends GTP2_ConnHdlr, PFCP_ConnHdlr, HTTP2_CT { var GTPv2_Emulation_CT vc_GTP2; port GTP2EM_PT TEIC0; var GTPv1U_Emulation_CT vc_GTP1U; @@ -77,6 +92,9 @@ var MutexDispCT vc_mutex_disp; var boolean g_pfcp_answer_heartbeat_req := true;
+ /* emulated SCP */ + var HTTP2_Server_Emulation_CT vc_HTTP2_SRV_SCP; + /* global test case guard timer (actual timeout value is set in f_init()) */ timer T_guard; } @@ -223,6 +241,18 @@
}
+private function f_init_http2_srv(charstring id) runs on SMF_Test_CT { + id := id & "-PFCP"; + + var Http2ServerEmulationCfg http2_srv_cfg := { + http2_bind_ip := mp_scp_local_ip, + http2_bind_port := mp_scp_local_port + }; + + vc_HTTP2_SRV_SCP := HTTP2_Server_Emulation_CT.create(id) alive; + vc_HTTP2_SRV_SCP.start(HTTP2_Server_Emulation.main(http2_srv_cfg)); +} + private function f_init(float guard_timeout := 60.0) runs on SMF_Test_CT { T_guard.start(guard_timeout); activate(as_Tguard()); @@ -232,6 +262,7 @@ f_init_gtp1u();
f_init_pfcp(id); + f_init_http2_srv(id);
if (mp_pcrf_local_ip != "") { f_init_diameter(testcasename()); @@ -260,6 +291,11 @@ connect(vc_conn:PFCP_PROC, vc_PFCP:CLIENT_PROC); f_MutexDisp_connect(vc_mutex_disp, vc_conn);
+ if (isbound(vc_HTTP2_SRV_SCP)) { + connect(vc_conn:HTTP2_CONN[HTTP2_CONN_SCP], vc_HTTP2_SRV_SCP:CONN); + connect(vc_conn:HTTP2_CONN_PROC[HTTP2_CONN_SCP], vc_HTTP2_SRV_SCP:CONN_PROC); + } + if (isbound(vc_Gx)) { connect(vc_conn:DIAMETER_PROC[DIA_Gx], vc_Gx:DIAMETER_PROC); connect(vc_conn:DIAMETER[DIA_Gx], vc_Gx:DIAMETER_CLIENT); @@ -279,6 +315,16 @@ return vc_conn; }
+function f_scp_uri_prefix() return charstring +{ + return "http://" & mp_scp_local_ip & ":" & int2str(mp_scp_local_port); +} +function f_amf_callback_uri(charstring imsi, charstring opcode, integer pduSessionId) return charstring +{ + return f_scp_uri_prefix() & + "/namf-callback/v1/imsi-" & imsi & "/" & opcode & "/" & int2str(pduSessionId); +} + /* send echo request; expect response */ testcase TC_tx_echo() runs on SMF_Test_CT { timer T := 5.0; @@ -452,6 +498,21 @@ vc_conn.done; }
+private function f_TC_n11_createSession_deleteSession() runs on SMF_Session_CT { + f_n11_init(); + f_n11_create_session(); + f_n11_delete_session(); + setverdict(pass); +} +testcase TC_n11_createSession_deleteSession() runs on SMF_Test_CT { + var SMF_Session_CT vc_conn; + var SessionPars pars := valueof(t_SessionPars('001010123456789'H, + rat_type := GTP2C_RAT_NR)); + f_init(); + vc_conn := f_start_handler(refers(f_TC_n11_createSession_deleteSession), pars); + vc_conn.done; +} + control { execute( TC_tx_echo() ); execute( TC_createSession_deleteSession() ); @@ -460,6 +521,8 @@ execute( TC_gy_ccr_update_rejected() ); execute( TC_s2b_createSession_v4_noapco() ); execute( TC_s2b_createSession_v4_apco() ); + + execute( TC_n11_createSession_deleteSession() ); }
diff --git a/smf/expected-results.xml b/smf/expected-results.xml index eba5484..a167103 100644 --- a/smf/expected-results.xml +++ b/smf/expected-results.xml @@ -7,4 +7,5 @@ <testcase classname='SMF_Tests' name='TC_gy_ccr_update_rejected' time='MASKED'/> <testcase classname='SMF_Tests' name='TC_s2b_createSession_v4_noapco' time='MASKED'/> <testcase classname='SMF_Tests' name='TC_s2b_createSession_v4_apco' time='MASKED'/> + <testcase classname='SMF_Tests' name='TC_n11_createSession_deleteSession' time='MASKED'/> </testsuite> diff --git a/smf/gen_links.sh b/smf/gen_links.sh index f8a3166..d1b3394 100755 --- a/smf/gen_links.sh +++ b/smf/gen_links.sh @@ -58,6 +58,18 @@ FILES="DIAMETER_EncDec.cc" gen_links $DIR $FILES
+DIR=$BASEDIR/titan.ProtocolModules.HTTP2/src +FILES="HTTP2_EncDec.cc HTTP2_Types.ttcn" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.ProtocolModules.JSON_v07_2006/src +FILES="JSON_Generic_Null_Def.asn JSON_Generic.ttcn" +gen_links $DIR $FILES + +DIR=$BASEDIR/osmo-ttcn3-openapi-generator/openapi-specs/3GPP_5GC_Rel19/ttcn3 +FILES="TS29571_CommonData.ttcn TS29502_Nsmf_PDUSession.ttcn TS29503_Nudm_SDM.ttcn TS29512_Npcf_SMPolicyControl.ttcn TS29518_Namf_Communication.ttcn " +gen_links $DIR $FILES + DIR=../library FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPCP_Types.ttcn IPCP_Templates.ttcn PAP_Types.ttcn " FILES+="GTPv1C_CodecPort.ttcn GTPv1C_CodecPort_CtrlFunct.ttcn GTPv1C_CodecPort_CtrlFunctDef.cc GTPv1C_Templates.ttcn Osmocom_Gb_Types.ttcn " @@ -70,6 +82,8 @@ FILES+="SCTP_Templates.ttcn " FILES+="NTP_Functions.ttcn PFCP_Templates.ttcn PFCP_CodecPort.ttcn PFCP_CodecPort_CtrlFunct.ttcn PFCP_CodecPort_CtrlFunctDef.cc PFCP_Emulation.ttcn " FILES+="Mutex.ttcn " +FILES+="HTTP2_CodecPort.ttcn HTTP2_CodecPort_CtrlFunct.ttcn HTTP2_CodecPort_CtrlFunctDef.cc HTTP2_Templates.ttcn HTTP2_Functions.ttcn HTTP2_Adapter.ttcn HTTP2_Server_Emulation.ttcn " +FILES+="TS29503_Nudm_SDM_Templates.ttcn TS29502_Nsmf_PDUSession_Templates.ttcn TS29512_Npcf_SMPolicyControl_Templates.ttcn TS29518_Namf_Communication_Templates.ttcn" gen_links $DIR $FILES
gen_links_finish diff --git a/smf/open5gs-nrf.yaml b/smf/open5gs-nrf.yaml index 0979be0..57f5b45 100644 --- a/smf/open5gs-nrf.yaml +++ b/smf/open5gs-nrf.yaml @@ -3,7 +3,7 @@ db_uri: mongodb://localhost/open5gs
logger: - level: info + level: debug
global: max: diff --git a/smf/open5gs-smf.yaml b/smf/open5gs-smf.yaml index 34aabc3..f37de82 100644 --- a/smf/open5gs-smf.yaml +++ b/smf/open5gs-smf.yaml @@ -1,7 +1,7 @@ # See https://github.com/open5gs/open5gs/blob/main/configs/open5gs/smf.yaml.in
logger: - level: info + level: debug
global: max: @@ -25,8 +25,8 @@ - address: 127.0.0.4 port: 7777 client: - nrf: - - uri: http://127.0.0.10:7777 + #nrf: + # - uri: http://127.0.0.10:7777 scp: - uri: http://127.0.1.10:7777 pfcp: diff --git a/smf/regen_makefile.sh b/smf/regen_makefile.sh index a2cb4bc..ad9ebd0 100755 --- a/smf/regen_makefile.sh +++ b/smf/regen_makefile.sh @@ -2,7 +2,7 @@
NAME=SMF_Tests
-FILES=" +FILES=" *.asn *.ttcn *.ttcnpp BSSGP_EncDec.cc @@ -13,6 +13,8 @@ GTPv1C_CodecPort_CtrlFunctDef.cc GTPv1U_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunctDef.cc + HTTP2_EncDec.cc + HTTP2_CodecPort_CtrlFunctDef.cc ICMP_EncDec.cc ICMPv6_EncDec.cc IPL4asp_PT.cc diff --git a/smf/testenv.cfg b/smf/testenv.cfg index b6cbb10..837073a 100644 --- a/smf/testenv.cfg +++ b/smf/testenv.cfg @@ -2,12 +2,6 @@ program=SMF_Tests config=SMF_Tests.cfg
-[nrf] -program=open5gs-nrfd -c open5gs-nrf.yaml -make=open5gs -package=open5gs-nrf -copy=open5gs-nrf.yaml - [smf] program=open5gs-smfd -c open5gs-smf.yaml make=open5gs