diff --git a/go.mod b/go.mod index ad42453..89f49da 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,12 @@ module github.com/free5gc/amf go 1.21 require ( - github.com/antihax/optional v1.0.0 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 github.com/davecgh/go-spew v1.1.1 - github.com/free5gc/aper v1.0.5 - github.com/free5gc/nas v1.1.4-0.20240807053650-6775d72a73b6 - github.com/free5gc/ngap v1.0.9-0.20240414165820-453b0aa37228 - github.com/free5gc/openapi v1.0.9-0.20240730084323-449098e08462 + github.com/free5gc/aper v1.0.6-0.20240503143507-2c4c4780b98f + github.com/free5gc/nas v1.1.4-0.20241107083120-4605e0d39ece + github.com/free5gc/ngap v1.0.9-0.20241107082718-d359a67ebfa2 + github.com/free5gc/openapi v1.0.9-0.20241116070448-943255152229 github.com/free5gc/sctp v1.0.1 github.com/free5gc/util v1.0.6 github.com/gin-gonic/gin v1.9.1 @@ -27,20 +26,23 @@ require ( require ( github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect - github.com/antonfisher/nested-logrus-formatter v1.3.1 // indirect github.com/bytedance/sonic v1.11.5 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.3 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.19.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/h2non/gock v1.2.0 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect @@ -58,6 +60,11 @@ require ( github.com/tim-ywliu/nested-logrus-formatter v1.3.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/arch v0.7.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/net v0.24.0 // indirect @@ -66,6 +73,5 @@ require ( golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/h2non/gock.v1 v1.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 67adb88..4fb9cce 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,6 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 h1:+JkXLHME8vLJafGhOH4aoV2Iu8bR55nU6iKMVfYVLjY= github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg= -github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= -github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/bytedance/sonic v1.11.5 h1:G00FYjjqll5iQ1PYXynbg/hyzqBqavH8Mo9/oTopd9k= @@ -23,14 +19,16 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/free5gc/aper v1.0.5 h1:sUYFFmOXDLjyL4rU6zFnq81M4YluqP90Pso5e/J4UhA= -github.com/free5gc/aper v1.0.5/go.mod h1:ybHxhYnRqQ9wD4yB9r/3MZdbCYCjtqUyfLpSnJpwWd4= -github.com/free5gc/nas v1.1.4-0.20240807053650-6775d72a73b6 h1:c8Z+AlgG6CPlOKTpoDhEnTtpOWW+clCr+88Ybe0hyog= -github.com/free5gc/nas v1.1.4-0.20240807053650-6775d72a73b6/go.mod h1:uhfoCLa/HKa975hKfob3wmdUiFMU2omTIWiRtYgn6XQ= -github.com/free5gc/ngap v1.0.9-0.20240414165820-453b0aa37228 h1:47Wa0ZdDI1r+IXbU6sVnMxRd9zZ4sQjXZxIQPXpitDg= -github.com/free5gc/ngap v1.0.9-0.20240414165820-453b0aa37228/go.mod h1:d5u7tYsBwxmLr3zw7wyBruRjc/gbdsHVhmdGFnVmfBU= -github.com/free5gc/openapi v1.0.9-0.20240730084323-449098e08462 h1:bK9UWqOhoddpAW9RfZRp4DPZNnPfEUeHvo4I86YAuzA= -github.com/free5gc/openapi v1.0.9-0.20240730084323-449098e08462/go.mod h1:afeuEQ21QCQDxZHnFjCmYrq3gBi+cd/WDNSUbaMcILo= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/free5gc/aper v1.0.6-0.20240503143507-2c4c4780b98f h1:sO8FFwAq7feSw/vKN9ioY+fX1gNTXd6/xQOqaeclzsA= +github.com/free5gc/aper v1.0.6-0.20240503143507-2c4c4780b98f/go.mod h1:oh3dtNsje2W4/q3pfidMWQKXbXIehXK3t6CD9tXmHx0= +github.com/free5gc/nas v1.1.4-0.20241107083120-4605e0d39ece h1:IC+OGynaXwurS2RIfno+2aKjlaFRQ6koZrC2QQu5yJ0= +github.com/free5gc/nas v1.1.4-0.20241107083120-4605e0d39ece/go.mod h1:/k8oW94r7D+lKAIFSIxZz0Qg/0tod/+oCJbsVZ2E7SU= +github.com/free5gc/ngap v1.0.9-0.20241107082718-d359a67ebfa2 h1:LMqqxvoDZAoG9xtfd5hhOiIDnPawSVcYof1nb6IkoWE= +github.com/free5gc/ngap v1.0.9-0.20241107082718-d359a67ebfa2/go.mod h1:uw13NF8Zdqp9LXlQCn9Xp2Ju3LSyki0GTyWEUAbUDbk= +github.com/free5gc/openapi v1.0.9-0.20241116070448-943255152229 h1:w3pvwFI5XABoj2J22Hrnn5rIbe0hJFzvsJCIsv8AX44= +github.com/free5gc/openapi v1.0.9-0.20241116070448-943255152229/go.mod h1:aKw6uGzEibGDrn9++w4/JpWxaaUBo7GaqsvuFKU9fl4= github.com/free5gc/sctp v1.0.1 h1:g8WDO97r8B9ubkT5Hyk9b4I1fZUOii9Z39gQ2eRaASo= github.com/free5gc/sctp v1.0.1/go.mod h1:7QXfRWCmlkBGD0EIu3qL5o71bslfIakydz4h2QDZdjQ= github.com/free5gc/util v1.0.6 h1:dBt9drcXtYKE/cY5XuQcuffgsYclPIpIArhSeS6M+DQ= @@ -41,6 +39,11 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -53,13 +56,15 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE= +github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -131,6 +136,16 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 h1:RtcvQ4iw3w9NBB5yRwgA4sSa82rfId7n4atVpvKx3bY= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0/go.mod h1:f/PbKbRd4cdUICWell6DmzvVJ7QrmBgFrRHjXmAXbK4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -156,8 +171,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= -gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/context/3gpp_types.go b/internal/context/3gpp_types.go index ef59f84..649025a 100644 --- a/internal/context/3gpp_types.go +++ b/internal/context/3gpp_types.go @@ -38,7 +38,7 @@ const ( ) type CauseAll struct { - Cause *models.Cause + Cause *models.SmfPduSessionCause NgapCause *models.NgApCause Var5GmmCause *int32 } diff --git a/internal/context/amf_ue.go b/internal/context/amf_ue.go index b0ef7df..6d584e1 100644 --- a/internal/context/amf_ue.go +++ b/internal/context/amf_ue.go @@ -70,7 +70,7 @@ type AmfUe struct { RetransmissionOfInitialNASMsg bool RequestIdentityType uint8 /* Used for AMF relocation */ - TargetAmfProfile *models.NfProfile + TargetAmfProfile *models.NrfNfDiscoveryNfProfile TargetAmfUri string /* Ue Identity */ PlmnId models.PlmnId @@ -97,7 +97,6 @@ type AmfUe struct { NudmSDMUri string ContextValid bool Reachability models.UeReachability - SubscribedData models.SubscribedData SmfSelectionData *models.SmfSelectionSubscriptionData UeContextInSmfData *models.UeContextInSmfData TraceData *models.TraceData @@ -121,7 +120,7 @@ type AmfUe struct { PcfUri string PolicyAssociationId string AmPolicyUri string - AmPolicyAssociation *models.PolicyAssociation + AmPolicyAssociation *models.PcfAmPolicyControlPolicyAssociation RequestTriggerLocationChange bool // true if AmPolicyAssociation.Trigger contains RequestTrigger_LOC_CH /* UeContextForHandover */ HandoverNotifyUri string @@ -204,7 +203,7 @@ type AmfUeEventSubscription struct { Timestamp time.Time AnyUe bool RemainReports *int32 - EventSubscription *models.AmfEventSubscription + EventSubscription *models.ExtAmfEventSubscription } type N1N2Message struct { @@ -658,7 +657,7 @@ func (ue *AmfUe) RemoveAmPolicyAssociation() { ue.PolicyAssociationId = "" } -func (ue *AmfUe) CopyDataFromUeContextModel(ueContext models.UeContext) { +func (ue *AmfUe) CopyDataFromUeContextModel(ueContext *models.UeContext) { if ueContext.Supi != "" { ue.Supi = ueContext.Supi ue.UnauthenticatedSupi = ueContext.SupiUnauthInd @@ -751,35 +750,45 @@ func (ue *AmfUe) CopyDataFromUeContextModel(ueContext models.UeContext) { if len(ueContext.AmPolicyReqTriggerList) > 0 { if ue.AmPolicyAssociation == nil { - ue.AmPolicyAssociation = new(models.PolicyAssociation) + ue.AmPolicyAssociation = new(models.PcfAmPolicyControlPolicyAssociation) } for _, trigger := range ueContext.AmPolicyReqTriggerList { switch trigger { - case models.AmPolicyReqTrigger_LOCATION_CHANGE: - ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, models.RequestTrigger_LOC_CH) - case models.AmPolicyReqTrigger_PRA_CHANGE: - ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, models.RequestTrigger_PRA_CH) - case models.AmPolicyReqTrigger_SARI_CHANGE: - ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, models.RequestTrigger_SERV_AREA_CH) - case models.AmPolicyReqTrigger_RFSP_INDEX_CHANGE: - ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, models.RequestTrigger_RFSP_CH) + case models.PolicyReqTrigger_LOCATION_CHANGE: + ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, + models.PcfAmPolicyControlRequestTrigger_LOC_CH) + case models.PolicyReqTrigger_PRA_CHANGE: + ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, + models.PcfAmPolicyControlRequestTrigger_PRA_CH) + case models.PolicyReqTrigger_ALLOWED_NSSAI_CHANGE: + ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, + models.PcfAmPolicyControlRequestTrigger_ALLOWED_NSSAI_CH) + case models.PolicyReqTrigger_NWDAF_DATA_CHANGE: + ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, + models.PcfAmPolicyControlRequestTrigger_NWDAF_DATA_CH) + case models.PolicyReqTrigger_SMF_SELECT_CHANGE: + ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, + models.PcfAmPolicyControlRequestTrigger_SMF_SELECT_CH) + case models.PolicyReqTrigger_ACCESS_TYPE_CHANGE: + ue.AmPolicyAssociation.Triggers = append(ue.AmPolicyAssociation.Triggers, + models.PcfAmPolicyControlRequestTrigger_ACCESS_TYPE_CH) } } } if len(ueContext.SessionContextList) > 0 { - for _, pduSessionContext := range ueContext.SessionContextList { + for index := range ueContext.SessionContextList { smContext := SmContext{ - pduSessionID: pduSessionContext.PduSessionId, - smContextRef: pduSessionContext.SmContextRef, - snssai: *pduSessionContext.SNssai, - dnn: pduSessionContext.Dnn, - accessType: pduSessionContext.AccessType, - hSmfID: pduSessionContext.HsmfId, - vSmfID: pduSessionContext.VsmfId, - nsInstance: pduSessionContext.NsInstance, + pduSessionID: ueContext.SessionContextList[index].PduSessionId, + smContextRef: ueContext.SessionContextList[index].SmContextRef, + snssai: *ueContext.SessionContextList[index].SNssai, + dnn: ueContext.SessionContextList[index].Dnn, + accessType: ueContext.SessionContextList[index].AccessType, + hSmfID: ueContext.SessionContextList[index].HsmfId, + vSmfID: ueContext.SessionContextList[index].VsmfId, + nsInstance: ueContext.SessionContextList[index].NsInstance, } - ue.StoreSmContext(pduSessionContext.PduSessionId, &smContext) + ue.StoreSmContext(ueContext.SessionContextList[index].PduSessionId, &smContext) } } diff --git a/internal/context/context.go b/internal/context/context.go index c22ed2a..cdd342b 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -38,7 +38,7 @@ func init() { GetSelf().RelativeCapacity = 0xff GetSelf().ServedGuamiList = make([]models.Guami, 0, MaxNumOfServedGuamiList) GetSelf().PlmnSupportList = make([]factory.PlmnSupportItem, 0, MaxNumOfPLMNs) - GetSelf().NfService = make(map[models.ServiceName]models.NfService) + GetSelf().NfService = make(map[models.ServiceName]models.NrfNfManagementNfService) GetSelf().NetworkName.Full = "free5GC" tmsiGenerator = idgenerator.NewGenerator(1, math.MaxInt32) amfStatusSubscriptionIDGenerator = idgenerator.NewGenerator(1, math.MaxInt32) @@ -64,7 +64,7 @@ type AMFContext struct { RelativeCapacity int64 NfId string Name string - NfService map[models.ServiceName]models.NfService // nfservice that amf support + NfService map[models.ServiceName]models.NrfNfManagementNfService // nfservice that amf support UriScheme models.UriScheme BindingIPv4 string SBIPort int @@ -241,7 +241,9 @@ func (context *AMFContext) AllocateRegistrationArea(ue *AmfUe, anType models.Acc } } -func (context *AMFContext) NewAMFStatusSubscription(subscriptionData models.SubscriptionData) (subscriptionID string) { +func (context *AMFContext) NewAMFStatusSubscription(subscriptionData models.AmfCommunicationSubscriptionData) ( + subscriptionID string, +) { id, err := amfStatusSubscriptionIDGenerator.Allocate() if err != nil { logger.CtxLog.Errorf("Allocate subscriptionID error: %+v", err) @@ -254,9 +256,11 @@ func (context *AMFContext) NewAMFStatusSubscription(subscriptionData models.Subs } // Return Value: (subscriptionData *models.SubScriptionData, ok bool) -func (context *AMFContext) FindAMFStatusSubscription(subscriptionID string) (*models.SubscriptionData, bool) { +func (context *AMFContext) FindAMFStatusSubscription(subscriptionID string) ( + *models.AmfCommunicationSubscriptionData, bool, +) { if value, ok := context.AMFStatusSubscriptions.Load(subscriptionID); ok { - subscriptionData := value.(models.SubscriptionData) + subscriptionData := value.(models.AmfCommunicationSubscriptionData) return &subscriptionData, ok } else { return nil, false @@ -489,10 +493,10 @@ func (context *AMFContext) InitNFService(serivceName []string, version string) { versionUri := "v" + tmpVersion[0] for index, nameString := range serivceName { name := models.ServiceName(nameString) - context.NfService[name] = models.NfService{ + context.NfService[name] = models.NrfNfManagementNfService{ ServiceInstanceId: strconv.Itoa(index), ServiceName: name, - Versions: &[]models.NfServiceVersion{ + Versions: []models.NfServiceVersion{ { ApiFullVersion: version, ApiVersionInUri: versionUri, @@ -501,10 +505,10 @@ func (context *AMFContext) InitNFService(serivceName []string, version string) { Scheme: context.UriScheme, NfServiceStatus: models.NfServiceStatus_REGISTERED, ApiPrefix: context.GetIPv4Uri(), - IpEndPoints: &[]models.IpEndPoint{ + IpEndPoints: []models.IpEndPoint{ { Ipv4Address: context.RegisterIPv4, - Transport: models.TransportProtocol_TCP, + Transport: models.NrfNfManagementTransportProtocol_TCP, Port: int32(context.SBIPort), }, }, @@ -557,13 +561,13 @@ func GetSelf() *AMFContext { return &amfContext } -func (c *AMFContext) GetTokenCtx(serviceName models.ServiceName, targetNF models.NfType) ( +func (c *AMFContext) GetTokenCtx(serviceName models.ServiceName, targetNF models.NrfNfManagementNfType) ( context.Context, *models.ProblemDetails, error, ) { if !c.OAuth2Required { return context.TODO(), nil, nil } - return oauth.GetTokenCtx(models.NfType_AMF, targetNF, + return oauth.GetTokenCtx(models.NrfNfManagementNfType_AMF, targetNF, c.NfId, c.NrfUri, string(serviceName)) } diff --git a/internal/gmm/handler.go b/internal/gmm/handler.go index 082765f..3d8232e 100644 --- a/internal/gmm/handler.go +++ b/internal/gmm/handler.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/antihax/optional" "github.com/mitchellh/mapstructure" "github.com/mohae/deepcopy" "github.com/pkg/errors" @@ -32,9 +31,8 @@ import ( "github.com/free5gc/nas/security" "github.com/free5gc/ngap/ngapConvert" "github.com/free5gc/ngap/ngapType" - "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/models" + Nnrf_NFDiscovery "github.com/free5gc/openapi/nrf/NFDiscovery" "github.com/free5gc/util/fsm" ) @@ -125,15 +123,15 @@ func transport5GSMMessage(ue *context.AmfUe, anType models.AccessType, smContext.StoreULNASTransport(ulNasTransport) // perform a local release of the PDU session identified by the PDU session ID and shall request // the SMF to perform a local release of the PDU session - updateData := models.SmContextUpdateData{ + updateData := models.SmfPduSessionSmContextUpdateData{ Release: true, - Cause: models.Cause_REL_DUE_TO_DUPLICATE_SESSION_ID, + Cause: models.SmfPduSessionCause_REL_DUE_TO_DUPLICATE_SESSION_ID, SmContextStatusUri: fmt.Sprintf("%s"+factory.AmfCallbackResUriPrefix+"/smContextStatus/%s/%d", ue.ServingAMF().GetIPv4Uri(), ue.Guti, pduSessionID), } ue.GmmLog.Warningf("Duplicated PDU session ID[%d]", pduSessionID) smContext.SetDuplicatedPduSessionID(true) - response, _, _, err := consumer.GetConsumer().SendUpdateSmContextRequest(smContext, updateData, nil, nil) + response, _, _, err := consumer.GetConsumer().SendUpdateSmContextRequest(smContext, &updateData, nil, nil) if err != nil { ue.GmmLog.Errorf("Failed to update smContext, local release SmContext[%d]", pduSessionID) ue.SmContextList.Delete(pduSessionID) @@ -252,7 +250,7 @@ func CreatePDUSession(ulNasTransport *nasMessage.ULNASTransport, if snssaiInfo, ok := ue.SmfSelectionData.SubscribedSnssaiInfos[snssaiStr]; ok { for _, dnnInfo := range snssaiInfo.DnnInfos { if dnnInfo.DefaultDnnIndicator { - dnn = dnnInfo.Dnn + dnn = dnnInfo.Dnn.(string) } } } @@ -268,7 +266,7 @@ func CreatePDUSession(ulNasTransport *nasMessage.ULNASTransport, ue.Lock.Lock() defer ue.Lock.Unlock() - _, smContextRef, errResponse, problemDetail, errSendReq := consumer.GetConsumer().SendCreateSmContextRequest( + smContextRef, errResponse, problemDetail, errSendReq := consumer.GetConsumer().SendCreateSmContextRequest( ue, newSmContext, nil, smMessage) if errSendReq != nil { ue.GmmLog.Errorf("CreateSmContextRequest Error: %+v", errSendReq) @@ -300,13 +298,12 @@ func forward5GSMMessageToSMF( smContext *context.SmContext, smMessage []byte, ) error { - smContextUpdateData := models.SmContextUpdateData{ + smContextUpdateData := models.SmfPduSessionSmContextUpdateData{ N1SmMsg: &models.RefToBinaryData{ ContentId: "N1SmMsg", }, } smContextUpdateData.Pei = ue.Pei - smContextUpdateData.Gpsi = ue.Gpsi if !context.CompareUserLocation(ue.Location, smContext.UserLocation()) { smContextUpdateData.UeLocation = &ue.Location } @@ -316,7 +313,7 @@ func forward5GSMMessageToSMF( } response, errResponse, problemDetail, err := consumer.GetConsumer().SendUpdateSmContextRequest(smContext, - smContextUpdateData, smMessage, nil) + &smContextUpdateData, smMessage, nil) if err != nil { // TODO: error handling @@ -482,7 +479,7 @@ func HandleRegistrationRequest(ue *context.AmfUe, anType models.AccessType, proc return fmt.Errorf("decode GUTI failed: %w", err) } guamiFromUeGuti = guamiFromUeGutiTmp - ue.PlmnId = *guamiFromUeGuti.PlmnId + ue.PlmnId = util.PlmnIdNidToModelsPlmnId(*guamiFromUeGuti.PlmnId) ue.GmmLog.Infof("MobileIdentity5GS: GUTI[%s]", guti) // TODO: support multiple ServedGuami @@ -578,11 +575,11 @@ func contextTransferFromOldAmf(ue *context.AmfUe, anType models.AccessType, oldA ue.GmmLog.Infof("ContextTransfer from old AMF[%s %s]", oldAmfGuami.PlmnId, oldAmfGuami.AmfId) amfSelf := context.GetSelf() - searchOpt := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - Guami: optional.NewInterface(openapi.MarshToJsonString(oldAmfGuami)), + searchOpt := Nnrf_NFDiscovery.SearchNFInstancesRequest{ + Guami: &oldAmfGuami, } - if err := consumer.GetConsumer().SearchAmfCommunicationInstance(ue, amfSelf.NrfUri, models.NfType_AMF, - models.NfType_AMF, &searchOpt); err != nil { + if err := consumer.GetConsumer().SearchAmfCommunicationInstance(ue, amfSelf.NrfUri, models.NrfNfManagementNfType_AMF, + models.NrfNfManagementNfType_AMF, &searchOpt); err != nil { return err } @@ -612,7 +609,7 @@ func contextTransferFromOldAmf(ue *context.AmfUe, anType models.AccessType, oldA ue.MacFailed = false } - ue.CopyDataFromUeContextModel(*ueContextTransferRspData.UeContext) + ue.CopyDataFromUeContextModel(ueContextTransferRspData.UeContext) if ue.SecurityContextAvailable { ue.DerivateAlgKey() } @@ -691,11 +688,11 @@ func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) erro } } - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - Supi: optional.NewString(ue.Supi), + param := Nnrf_NFDiscovery.SearchNFInstancesRequest{ + Supi: &ue.Supi, } if amfSelf.Locality != "" { - param.PreferredLocality = optional.NewString(amfSelf.Locality) + param.PreferredLocality = &amfSelf.Locality } // TODO: (step 15) Should use PCF ID to select PCF @@ -705,17 +702,17 @@ func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) erro // } for { resp, err := consumer.GetConsumer().SendSearchNFInstances( - amfSelf.NrfUri, models.NfType_PCF, models.NfType_AMF, ¶m) + amfSelf.NrfUri, models.NrfNfManagementNfType_PCF, models.NrfNfManagementNfType_AMF, ¶m) if err != nil { ue.GmmLog.Error("AMF can not select an PCF by NRF") } else { // select the first PCF, TODO: select base on other info var pcfUri string - for _, nfProfile := range resp.NfInstances { - pcfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NPCF_AM_POLICY_CONTROL, + for index := range resp.NfInstances { + pcfUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfServiceStatus_REGISTERED) if pcfUri != "" { - ue.PcfId = nfProfile.NfInstanceId + ue.PcfId = resp.NfInstances[index].NfInstanceId break } } @@ -924,8 +921,8 @@ func HandleMobilityAndPeriodicRegistrationUpdating(ue *context.AmfUe, anType mod } if ue.LocationChanged && ue.RequestTriggerLocationChange { - updateReq := models.PolicyAssociationUpdateRequest{} - updateReq.Triggers = append(updateReq.Triggers, models.RequestTrigger_LOC_CH) + updateReq := models.PcfAmPolicyControlPolicyAssociationUpdateRequest{} + updateReq.Triggers = append(updateReq.Triggers, models.PcfAmPolicyControlRequestTrigger_LOC_CH) updateReq.UserLoc = &ue.Location problemDetails, err := consumer.GetConsumer().AMPolicyControlUpdate(ue, updateReq) if problemDetails != nil { @@ -1005,20 +1002,22 @@ func communicateWithUDM(ue *context.AmfUe, accessType models.AccessType) error { // UDM selection described in TS 23.501 6.3.8 // TODO: consider udm group id, Routing ID part of SUCI, GPSI or External Group ID (e.g., by the NEF) - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - Supi: optional.NewString(ue.Supi), + param := Nnrf_NFDiscovery.SearchNFInstancesRequest{ + Supi: &ue.Supi, } resp, err := consumer.GetConsumer().SendSearchNFInstances( - amfSelf.NrfUri, models.NfType_UDM, models.NfType_AMF, ¶m) + amfSelf.NrfUri, models.NrfNfManagementNfType_UDM, models.NrfNfManagementNfType_AMF, ¶m) if err != nil { return errors.Errorf("AMF can not select an UDM by NRF: SendSearchNFInstances failed") } var uecmUri, sdmUri string - for _, nfProfile := range resp.NfInstances { - ue.UdmId = nfProfile.NfInstanceId - uecmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_UECM, models.NfServiceStatus_REGISTERED) - sdmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_SDM, models.NfServiceStatus_REGISTERED) + for index := range resp.NfInstances { + ue.UdmId = resp.NfInstances[index].NfInstanceId + uecmUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NUDM_UECM, + models.NfServiceStatus_REGISTERED) + sdmUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NUDM_SDM, + models.NfServiceStatus_REGISTERED) if uecmUri != "" && sdmUri != "" { break } @@ -1073,12 +1072,12 @@ func communicateWithUDM(ue *context.AmfUe, accessType models.AccessType) error { func getSubscribedNssai(ue *context.AmfUe) { amfSelf := context.GetSelf() if ue.NudmSDMUri == "" { - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - Supi: optional.NewString(ue.Supi), + param := Nnrf_NFDiscovery.SearchNFInstancesRequest{ + Supi: &ue.Supi, } for { err := consumer.GetConsumer().SearchUdmSdmInstance( - ue, amfSelf.NrfUri, models.NfType_UDM, models.NfType_AMF, ¶m) + ue, amfSelf.NrfUri, models.NrfNfManagementNfType_UDM, models.NrfNfManagementNfType_AMF, ¶m) if err != nil { ue.GmmLog.Errorf("AMF can not select an Nudm_SDM Instance by NRF[Error: %+v]", err) time.Sleep(2 * time.Second) @@ -1141,8 +1140,9 @@ func handleRequestedNssai(ue *context.AmfUe, anType models.AccessType) error { if needSliceSelection { if ue.NssfUri == "" { for { + reqParam := Nnrf_NFDiscovery.SearchNFInstancesRequest{} errSearchNssf := consumer.GetConsumer().SearchNssfNSSelectionInstance( - ue, amfSelf.NrfUri, models.NfType_NSSF, models.NfType_AMF, nil) + ue, amfSelf.NrfUri, models.NrfNfManagementNfType_NSSF, models.NrfNfManagementNfType_AMF, &reqParam) if errSearchNssf != nil { ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", errSearchNssf) time.Sleep(2 * time.Second) @@ -1176,7 +1176,7 @@ func handleRequestedNssai(ue *context.AmfUe, anType models.AccessType) error { } // Step 6 - searchTargetAmfQueryParam := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{} + searchTargetAmfQueryParam := Nnrf_NFDiscovery.SearchNFInstancesRequest{} if ue.NetworkSliceInfo != nil { networkSliceInfo := ue.NetworkSliceInfo if networkSliceInfo.TargetAmfSet != "" { @@ -1190,24 +1190,22 @@ func handleRequestedNssai(ue *context.AmfUe, anType models.AccessType) error { Mnc: targetAmfSetToken[1], } - if !reflect.DeepEqual(*guami.PlmnId, targetAmfPlmnId) { - searchTargetAmfQueryParam.TargetPlmnList = optional. - NewInterface(openapi.MarshToJsonString([]models.PlmnId{targetAmfPlmnId})) - searchTargetAmfQueryParam.RequesterPlmnList = optional. - NewInterface(openapi.MarshToJsonString([]models.PlmnId{*guami.PlmnId})) + if !reflect.DeepEqual(util.PlmnIdNidToModelsPlmnId(*guami.PlmnId), targetAmfPlmnId) { + searchTargetAmfQueryParam.TargetPlmnList = []models.PlmnId{targetAmfPlmnId} + searchTargetAmfQueryParam.RequesterPlmnList = []models.PlmnId{util.PlmnIdNidToModelsPlmnId(*guami.PlmnId)} } - searchTargetAmfQueryParam.AmfRegionId = optional.NewString(targetAmfSetToken[2]) - searchTargetAmfQueryParam.AmfSetId = optional.NewString(targetAmfSetToken[3]) + searchTargetAmfQueryParam.AmfRegionId = &targetAmfSetToken[2] + searchTargetAmfQueryParam.AmfSetId = &targetAmfSetToken[3] } else if len(networkSliceInfo.CandidateAmfList) > 0 { // TODO: select candidate Amf based on local poilcy - searchTargetAmfQueryParam.TargetNfInstanceId = optional.NewInterface(networkSliceInfo.CandidateAmfList[0]) + searchTargetAmfQueryParam.TargetNfInstanceId = &networkSliceInfo.CandidateAmfList[0] } } sendReroute := true err = consumer.GetConsumer().SearchAmfCommunicationInstance(ue, amfSelf.NrfUri, - models.NfType_AMF, models.NfType_AMF, &searchTargetAmfQueryParam) + models.NrfNfManagementNfType_AMF, models.NrfNfManagementNfType_AMF, &searchTargetAmfQueryParam) if err == nil { // Condition (A) Step 7: initial AMF find Target AMF via NRF -> // Send Namf_Communication_N1MessageNotify to Target AMF @@ -1291,7 +1289,7 @@ func assignLadnInfo(ue *context.AmfUe, accessType models.AccessType) { } else { for _, snssaiInfos := range ue.SmfSelectionData.SubscribedSnssaiInfos { for _, dnnInfo := range snssaiInfos.DnnInfos { - if ladn, ok := amfSelf.LadnPool[dnnInfo.Dnn]; ok { // check if this dnn is a ladn + if ladn, ok := amfSelf.LadnPool[dnnInfo.Dnn.(string)]; ok { // check if this dnn is a ladn if ue.TaiListInRegistrationArea(ladn.TaiList, accessType) { ue.LadnInfo = append(ue.LadnInfo, ladn) } @@ -1313,7 +1311,7 @@ func assignLadnInfo(ue *context.AmfUe, accessType models.AccessType) { for _, snssaiInfos := range ue.SmfSelectionData.SubscribedSnssaiInfos { for _, dnnInfo := range snssaiInfos.DnnInfos { if dnnInfo.Dnn != "*" { - if ladn, ok := amfSelf.LadnPool[dnnInfo.Dnn]; ok { + if ladn, ok := amfSelf.LadnPool[dnnInfo.Dnn.(string)]; ok { if ue.TaiListInRegistrationArea(ladn.TaiList, accessType) { ue.LadnInfo = append(ue.LadnInfo, ladn) } @@ -1402,7 +1400,7 @@ func releaseInactivePDUSession(ue *context.AmfUe, anType models.AccessType, uePd // perform a local release of all those PDU session which are in 5GSM state PDU SESSION ACTIVE // on the AMF side associated with the access type the REGISTRATION REQUEST message is sent over, // but are indicated by the UE as being in 5GSM state PDU SESSION INACTIVE - cause := models.Cause_PDU_SESSION_STATUS_MISMATCH + cause := models.SmfPduSessionCause_PDU_SESSION_STATUS_MISMATCH causeAll := &context.CauseAll{ Cause: &cause, } @@ -1596,7 +1594,7 @@ func HandleNotificationResponse(ue *context.AmfUe, notificationResponse *nasMess pduSessionId := int32(psi) if smContext, ok := ue.SmContextFindByPDUSessionID(pduSessionId); ok { if !psiArray[psi] { - cause := models.Cause_PDU_SESSION_STATUS_MISMATCH + cause := models.SmfPduSessionCause_PDU_SESSION_STATUS_MISMATCH causeAll := &context.CauseAll{ Cause: &cause, } @@ -1650,9 +1648,9 @@ func AuthenticationProcedure(ue *context.AmfUe, accessType models.AccessType) (b amfSelf := context.GetSelf() // TODO: consider ausf group id, Routing ID part of SUCI - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{} + param := Nnrf_NFDiscovery.SearchNFInstancesRequest{} resp, err := consumer.GetConsumer().SendSearchNFInstances( - amfSelf.NrfUri, models.NfType_AUSF, models.NfType_AMF, ¶m) + amfSelf.NrfUri, models.NrfNfManagementNfType_AUSF, models.NrfNfManagementNfType_AMF, ¶m) if err != nil { ue.GmmLog.Error("AMF can not select an AUSF by NRF") gmm_message.SendRegistrationReject(ue.RanUe[accessType], nasMessage.Cause5GMMCongestion, "") @@ -1661,9 +1659,10 @@ func AuthenticationProcedure(ue *context.AmfUe, accessType models.AccessType) (b // select the first AUSF, TODO: select base on other info var ausfUri string - for _, nfProfile := range resp.NfInstances { - ue.AusfId = nfProfile.NfInstanceId - ausfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NAUSF_AUTH, models.NfServiceStatus_REGISTERED) + for index := range resp.NfInstances { + ue.AusfId = resp.NfInstances[index].NfInstanceId + ausfUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NAUSF_AUTH, + models.NfServiceStatus_REGISTERED) if ausfUri != "" { break } @@ -1869,7 +1868,7 @@ func HandleServiceRequest(ue *context.AmfUe, anType models.AccessType, errPduSessionId, errCause = reestablishAllowedPDUSessionOver3GPP(ue, anType, smContext, &allowPduSessionPsi, &cxtList, reactivationResult, errPduSessionId, errCause) } - } else if smInfo.N2InfoContent.NgapIeType == models.NgapIeType_PDU_RES_SETUP_REQ { + } else if smInfo.N2InfoContent.NgapIeType == models.AmfCommunicationNgapIeType_PDU_RES_SETUP_REQ { var nasPdu []byte var err error if n1Msg != nil { @@ -1952,7 +1951,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp } switch ue.AuthenticationCtx.AuthType { - case models.AuthType__5_G_AKA: + case models.AusfUeAuthenticationAuthType__5_G_AKA: var av5gAka models.Av5gAka if err := mapstructure.Decode(ue.AuthenticationCtx.Var5gAuthData, &av5gAka); err != nil { return fmt.Errorf("Var5gAuthData Convert Type Error") @@ -1999,7 +1998,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp return nil } switch response.AuthResult { - case models.AuthResult_SUCCESS: + case models.AusfUeAuthenticationAuthResult_SUCCESS: ue.UnauthenticatedSupi = false ue.Kseaf = response.Kseaf ue.Supi = response.Supi @@ -2011,7 +2010,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp ArgEAPSuccess: false, ArgEAPMessage: "", }, logger.GmmLog) - case models.AuthResult_FAILURE: + case models.AusfUeAuthenticationAuthResult_FAILURE: if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 { ue.IdentityRequestSendTimes++ gmm_message.SendIdentityRequest(ue.RanUe[accessType], accessType, nasMessage.MobileIdentity5GSTypeSuci) @@ -2024,7 +2023,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp }, logger.GmmLog) } } - case models.AuthType_EAP_AKA_PRIME: + case models.AusfUeAuthenticationAuthType_EAP_AKA_PRIME: response, pd, err := consumer.GetConsumer().SendEapAuthConfirmRequest(ue, *authenticationResponse.EAPMessage) if err != nil { return err @@ -2034,7 +2033,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp } switch response.AuthResult { - case models.AuthResult_SUCCESS: + case models.AusfUeAuthenticationAuthResult_SUCCESS: ue.UnauthenticatedSupi = false ue.Kseaf = response.KSeaf ue.Supi = response.Supi @@ -2047,7 +2046,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp ArgEAPSuccess: true, ArgEAPMessage: response.EapPayload, }, logger.GmmLog) - case models.AuthResult_FAILURE: + case models.AusfUeAuthenticationAuthResult_FAILURE: if ue.IdentityTypeUsedForRegistration == nasMessage.MobileIdentity5GSType5gGuti && ue.IdentityRequestSendTimes == 0 { ue.IdentityRequestSendTimes++ gmm_message.SendAuthenticationResult(ue.RanUe[accessType], false, response.EapPayload) @@ -2060,7 +2059,7 @@ func HandleAuthenticationResponse(ue *context.AmfUe, accessType models.AccessTyp ArgAccessType: accessType, }, logger.GmmLog) } - case models.AuthResult_ONGOING: + case models.AusfUeAuthenticationAuthResult_ONGOING: ue.AuthenticationCtx.Var5gAuthData = response.EapPayload if _, exists := response.Links["eap-session"]; exists { ue.AuthenticationCtx.Links = response.Links @@ -2090,7 +2089,7 @@ func HandleAuthenticationFailure(ue *context.AmfUe, anType models.AccessType, cause5GMM := authenticationFailure.Cause5GMM.GetCauseValue() - if ue.AuthenticationCtx.AuthType == models.AuthType__5_G_AKA { + if ue.AuthenticationCtx.AuthType == models.AusfUeAuthenticationAuthType__5_G_AKA { switch cause5GMM { case nasMessage.Cause5GMMMACFailure: ue.GmmLog.Warnln("Authentication Failure Cause: Mac Failure") @@ -2172,7 +2171,7 @@ func HandleAuthenticationFailure(ue *context.AmfUe, anType models.AccessType, gmm_message.SendAuthenticationRequest(ue.RanUe[anType]) } - } else if ue.AuthenticationCtx.AuthType == models.AuthType_EAP_AKA_PRIME { + } else if ue.AuthenticationCtx.AuthType == models.AusfUeAuthenticationAuthType_EAP_AKA_PRIME { switch cause5GMM { case nasMessage.Cause5GMMngKSIAlreadyInUse: ue.GmmLog.Warn("Authentication Failure 5GMM Cause: NgKSI Already In Use") diff --git a/internal/gmm/message/build.go b/internal/gmm/message/build.go index f9f93a8..d97350d 100644 --- a/internal/gmm/message/build.go +++ b/internal/gmm/message/build.go @@ -126,7 +126,7 @@ func BuildAuthenticationRequest(ue *context.AmfUe, accessType models.AccessType) authenticationRequest.ABBA.SetABBAContents(ue.ABBA) switch ue.AuthenticationCtx.AuthType { - case models.AuthType__5_G_AKA: + case models.AusfUeAuthenticationAuthType__5_G_AKA: var tmpArray [16]byte var av5gAka models.Av5gAka @@ -153,7 +153,7 @@ func BuildAuthenticationRequest(ue *context.AmfUe, accessType models.AccessType) authenticationRequest.AuthenticationParameterAUTN.SetLen(uint8(len(autn))) copy(tmpArray[:], autn[0:16]) authenticationRequest.AuthenticationParameterAUTN.SetAUTN(tmpArray) - case models.AuthType_EAP_AKA_PRIME: + case models.AusfUeAuthenticationAuthType_EAP_AKA_PRIME: eapMsg := ue.AuthenticationCtx.Var5gAuthData.(string) rawEapMsg, err := base64.StdEncoding.DecodeString(eapMsg) if err != nil { diff --git a/internal/nas/fuzz_test.go b/internal/nas/fuzz_test.go index 224fa98..b220854 100644 --- a/internal/nas/fuzz_test.go +++ b/internal/nas/fuzz_test.go @@ -24,7 +24,7 @@ import ( func FuzzHandleNAS(f *testing.F) { amfSelf := amf_context.GetSelf() amfSelf.ServedGuamiList = []models.Guami{{ - PlmnId: &models.PlmnId{ + PlmnId: &models.PlmnIdNid{ Mcc: "208", Mnc: "93", }, @@ -118,7 +118,7 @@ func FuzzHandleNAS(f *testing.F) { func FuzzHandleNAS2(f *testing.F) { amfSelf := amf_context.GetSelf() amfSelf.ServedGuamiList = []models.Guami{{ - PlmnId: &models.PlmnId{ + PlmnId: &models.PlmnIdNid{ Mcc: "208", Mnc: "93", }, @@ -238,7 +238,7 @@ func FuzzHandleNAS2(f *testing.F) { amfUe.State[models.AccessType__3_GPP_ACCESS].Set(amf_context.Authentication) amfUe.RequestIdentityType = nasMessage.MobileIdentity5GSTypeSuci amfUe.AuthenticationCtx = &models.UeAuthenticationCtx{ - AuthType: models.AuthType__5_G_AKA, + AuthType: models.AusfUeAuthenticationAuthType__5_G_AKA, } amf_nas.HandleNAS(ue, ngapType.ProcedureCodeUplinkNASTransport, d, false) }) diff --git a/internal/ngap/handler_test.go b/internal/ngap/handler_test.go index 8ed5d41..9bde0c7 100644 --- a/internal/ngap/handler_test.go +++ b/internal/ngap/handler_test.go @@ -79,7 +79,7 @@ func NewAmfContext(amfCtx *amf_context.AMFContext) { SBIPort: 8000, ServedGuamiList: []models.Guami{ { - PlmnId: &models.PlmnId{ + PlmnId: &models.PlmnIdNid{ Mcc: "208", Mnc: "93", }, diff --git a/internal/ngap/message/build.go b/internal/ngap/message/build.go index 5c4cf12..b2436fd 100644 --- a/internal/ngap/message/build.go +++ b/internal/ngap/message/build.go @@ -7,6 +7,7 @@ import ( "github.com/free5gc/amf/internal/context" "github.com/free5gc/amf/internal/logger" + "github.com/free5gc/amf/internal/util" "github.com/free5gc/amf/pkg/factory" "github.com/free5gc/aper" "github.com/free5gc/ngap" @@ -116,7 +117,7 @@ func BuildNGSetupResponse() ([]byte, error) { servedGUAMIList := ie.Value.ServedGUAMIList for _, guami := range amfSelf.ServedGuamiList { servedGUAMIItem := ngapType.ServedGUAMIItem{} - servedGUAMIItem.GUAMI.PLMNIdentity = ngapConvert.PlmnIdToNgap(*guami.PlmnId) + servedGUAMIItem.GUAMI.PLMNIdentity = ngapConvert.PlmnIdToNgap(util.PlmnIdNidToModelsPlmnId(*guami.PlmnId)) regionId, setId, prtId := ngapConvert.AmfIdToNgap(guami.AmfId) servedGUAMIItem.GUAMI.AMFRegionID.Value = regionId servedGUAMIItem.GUAMI.AMFSetID.Value = setId @@ -1004,7 +1005,7 @@ func BuildInitialContextSetupRequest( servedGuami := amfSelf.ServedGuamiList[0] - *plmnID = ngapConvert.PlmnIdToNgap(*servedGuami.PlmnId) + *plmnID = ngapConvert.PlmnIdToNgap(util.PlmnIdNidToModelsPlmnId(*servedGuami.PlmnId)) amfRegionID.Value, amfSetID.Value, amfPtrID.Value = ngapConvert.AmfIdToNgap(servedGuami.AmfId) initialContextSetupRequestIEs.List = append(initialContextSetupRequestIEs.List, ie) @@ -1801,7 +1802,7 @@ func BuildHandoverRequest(ue *context.RanUe, cause ngapType.Cause, servedGuami := amfSelf.ServedGuamiList[0] - *plmnID = ngapConvert.PlmnIdToNgap(*servedGuami.PlmnId) + *plmnID = ngapConvert.PlmnIdToNgap(util.PlmnIdNidToModelsPlmnId(*servedGuami.PlmnId)) amfRegionID.Value, amfSetID.Value, amfPtrID.Value = ngapConvert.AmfIdToNgap(servedGuami.AmfId) handoverRequestIEs.List = append(handoverRequestIEs.List, ie) @@ -2996,7 +2997,7 @@ func BuildAMFConfigurationUpdate(tNLassociationUsage ngapType.TNLAssociationUsag servedGUAMIList := ie.Value.ServedGUAMIList for _, guami := range amfSelf.ServedGuamiList { servedGUAMIItem := ngapType.ServedGUAMIItem{} - servedGUAMIItem.GUAMI.PLMNIdentity = ngapConvert.PlmnIdToNgap(*guami.PlmnId) + servedGUAMIItem.GUAMI.PLMNIdentity = ngapConvert.PlmnIdToNgap(util.PlmnIdNidToModelsPlmnId(*guami.PlmnId)) regionId, setId, prtId := ngapConvert.AmfIdToNgap(guami.AmfId) servedGUAMIItem.GUAMI.AMFRegionID.Value = regionId servedGUAMIItem.GUAMI.AMFSetID.Value = setId diff --git a/internal/ngap/message/forward_ie.go b/internal/ngap/message/forward_ie.go index f62543c..1706056 100644 --- a/internal/ngap/message/forward_ie.go +++ b/internal/ngap/message/forward_ie.go @@ -5,6 +5,7 @@ import ( "github.com/free5gc/amf/internal/context" "github.com/free5gc/amf/internal/logger" + "github.com/free5gc/amf/internal/util" "github.com/free5gc/ngap/ngapConvert" "github.com/free5gc/ngap/ngapType" "github.com/free5gc/openapi/models" @@ -175,7 +176,7 @@ func BuildIEMobilityRestrictionList(ue *context.AmfUe) ngapType.MobilityRestrict func BuildUnavailableGUAMIList(guamiList []models.Guami) (unavailableGUAMIList ngapType.UnavailableGUAMIList) { for _, guami := range guamiList { item := ngapType.UnavailableGUAMIItem{} - item.GUAMI.PLMNIdentity = ngapConvert.PlmnIdToNgap(*guami.PlmnId) + item.GUAMI.PLMNIdentity = ngapConvert.PlmnIdToNgap(util.PlmnIdNidToModelsPlmnId(*guami.PlmnId)) regionId, setId, ptrId := ngapConvert.AmfIdToNgap(guami.AmfId) item.GUAMI.AMFRegionID.Value = regionId item.GUAMI.AMFSetID.Value = setId diff --git a/internal/sbi/api_communication.go b/internal/sbi/api_communication.go index 4e58649..f5c4c8f 100644 --- a/internal/sbi/api_communication.go +++ b/internal/sbi/api_communication.go @@ -26,76 +26,103 @@ func (s *Server) getCommunicationRoutes() []Route { }, }, { + Name: "AMFStatusChangeSubscribeModfy", Method: http.MethodPut, Pattern: "/subscriptions/:subscriptionId", APIFunc: s.HTTPAMFStatusChangeSubscribeModify, }, { + Name: "AMFStatusChangeUnSubscribe", Method: http.MethodDelete, Pattern: "/subscriptions/:subscriptionId", APIFunc: s.HTTPAMFStatusChangeUnSubscribe, }, { + Name: "CreateUEContext", Method: http.MethodPut, Pattern: "/ue-contexts/:ueContextId", APIFunc: s.HTTPCreateUEContext, }, { + Name: "EBIAssignment", Method: http.MethodPost, Pattern: "/ue-contexts/:ueContextId/assign-ebi", APIFunc: s.HTTPEBIAssignment, }, { + Name: "RegistrationStatusUpdate", Method: http.MethodPost, Pattern: "/ue-contexts/:ueContextId/transfer-update", APIFunc: s.HTTPRegistrationStatusUpdate, }, { + Name: "ReleaseUEContext", Method: http.MethodPost, Pattern: "/ue-contexts/:ueContextId/release", APIFunc: s.HTTPReleaseUEContext, }, { + Name: "UEContextTransfer", Method: http.MethodPost, Pattern: "/ue-contexts/:ueContextId/transfer", APIFunc: s.HTTPUEContextTransfer, }, { + Name: "RelocateUEContext", + Method: http.MethodPost, + Pattern: "/ue-contexts/:ueContextId/relocate", + APIFunc: s.HTTPRelocateUEContext, + }, + { + Name: "CancelRelocateUEContext", + Method: http.MethodPost, + Pattern: "/ue-contexts/:ueContextId/cancel-relocate", + APIFunc: s.HTTPCancelRelocateUEContext, + }, + { + Name: "N1N2MessageUnSubscribe", Method: http.MethodDelete, Pattern: "/ue-contexts/:ueContextId/n1-n2-messages/subscriptions/:subscriptionId", APIFunc: s.HTTPN1N2MessageUnSubscribe, }, { + Name: "N1N2MessageTransfer", Method: http.MethodPost, Pattern: "/ue-contexts/:ueContextId/n1-n2-messages", APIFunc: s.HTTPN1N2MessageTransfer, }, { + Name: "N1N2MessageTransferStatus", Method: http.MethodGet, Pattern: "/ue-contexts/:ueContextId/n1-n2-messages/:n1N2MessageId", APIFunc: s.HTTPN1N2MessageTransferStatus, }, { + Name: "N1N2MessageSubscribe", Method: http.MethodPost, Pattern: "/ue-contexts/:ueContextId/n1-n2-messages/subscriptions", APIFunc: s.HTTPN1N2MessageSubscribe, }, { + Name: "NonUeN2InfoUnSubscribe", Method: http.MethodDelete, Pattern: "/non-ue-n2-messages/subscriptions/:n2NotifySubscriptionId", APIFunc: s.HTTPNonUeN2InfoUnSubscribe, }, { + Name: "NonUeN2MessageTransfer", Method: http.MethodPost, Pattern: "/non-ue-n2-messages/transfer", APIFunc: s.HTTPNonUeN2MessageTransfer, }, { + Name: "NonUeN2InfoSubscribe", Method: http.MethodPost, Pattern: "/non-ue-n2-messages/subscriptions", APIFunc: s.HTTPNonUeN2InfoSubscribe, }, { + Name: "AMFStatusChangeSubscribe", Method: http.MethodPost, Pattern: "/subscriptions", APIFunc: s.HTTPAMFStatusChangeSubscribe, @@ -105,7 +132,7 @@ func (s *Server) getCommunicationRoutes() []Route { // AMFStatusChangeSubscribeModify - Namf_Communication AMF Status Change Subscribe Modify service Operation func (s *Server) HTTPAMFStatusChangeSubscribeModify(c *gin.Context) { - var subscriptionData models.SubscriptionData + var subscriptionData models.AmfCommunicationSubscriptionData requestBody, err := c.GetRawData() if err != nil { @@ -319,6 +346,14 @@ func (s *Server) HTTPUEContextTransfer(c *gin.Context) { s.Processor().HandleUEContextTransferRequest(c, ueContextTransferRequest) } +func (s *Server) HTTPRelocateUEContext(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) HTTPCancelRelocateUEContext(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + func (s *Server) HTTPN1N2MessageUnSubscribe(c *gin.Context) { s.Processor().HandleN1N2MessageUnSubscribeRequest(c) } @@ -416,7 +451,7 @@ func (s *Server) HTTPNonUeN2InfoSubscribe(c *gin.Context) { } func (s *Server) HTTPAMFStatusChangeSubscribe(c *gin.Context) { - var subscriptionData models.SubscriptionData + var subscriptionData models.AmfCommunicationSubscriptionData requestBody, err := c.GetRawData() if err != nil { diff --git a/internal/sbi/api_eventexposure.go b/internal/sbi/api_eventexposure.go index 1f019f8..908ba74 100644 --- a/internal/sbi/api_eventexposure.go +++ b/internal/sbi/api_eventexposure.go @@ -20,16 +20,19 @@ func (s *Server) getEventexposureRoutes() []Route { }, }, { + Name: "DeleteSubscription", Method: http.MethodDelete, Pattern: "/subscriptions/:subscriptionId", APIFunc: s.HTTPDeleteSubscription, }, { + Name: "ModifySubscription", Method: http.MethodPatch, Pattern: "/subscriptions/:subscriptionId", APIFunc: s.HTTPModifySubscription, }, { + Name: "CreateSubscription", Method: http.MethodPost, Pattern: "/subscriptions", APIFunc: s.HTTPCreateSubscription, diff --git a/internal/sbi/api_httpcallback.go b/internal/sbi/api_httpcallback.go index fb47e2a..e23d8a8 100644 --- a/internal/sbi/api_httpcallback.go +++ b/internal/sbi/api_httpcallback.go @@ -21,21 +21,25 @@ func (s *Server) getHttpCallBackRoutes() []Route { }, }, { + Name: "AmPolicyControlUpdateNotifyUpdate", Method: http.MethodPost, Pattern: "/am-policy/:polAssoId/update", APIFunc: s.HTTPAmPolicyControlUpdateNotifyUpdate, }, { + Name: "AmPolicyControlUpdateNotifyTerminate", Method: http.MethodPost, Pattern: "/am-policy/:polAssoId/terminate", APIFunc: s.HTTPAmPolicyControlUpdateNotifyTerminate, }, { + Name: "N1MessageNotify", Method: http.MethodPost, Pattern: "/n1-message-notify", APIFunc: s.HTTPN1MessageNotify, }, { + Name: "HandleDeregistrationNotification", Method: http.MethodPost, Pattern: "/deregistration/:ueid", APIFunc: s.HTTPHandleDeregistrationNotification, @@ -44,7 +48,7 @@ func (s *Server) getHttpCallBackRoutes() []Route { } func (s *Server) HTTPAmPolicyControlUpdateNotifyUpdate(c *gin.Context) { - var policyUpdate models.PolicyUpdate + var policyUpdate models.PcfAmPolicyControlPolicyUpdate requestBody, err := c.GetRawData() if err != nil { @@ -75,7 +79,7 @@ func (s *Server) HTTPAmPolicyControlUpdateNotifyUpdate(c *gin.Context) { } func (s *Server) HTTPAmPolicyControlUpdateNotifyTerminate(c *gin.Context) { - var terminationNotification models.TerminationNotification + var terminationNotification models.PcfAmPolicyControlTerminationNotification requestBody, err := c.GetRawData() if err != nil { @@ -106,22 +110,10 @@ func (s *Server) HTTPAmPolicyControlUpdateNotifyTerminate(c *gin.Context) { } func (s *Server) HTTPN1MessageNotify(c *gin.Context) { - var n1MessageNotify models.N1MessageNotify + var n1MessageNotify models.N1MessageNotifyRequest + n1MessageNotify.JsonData = new(models.N1MessageNotification) - requestBody, err := c.GetRawData() - if err != nil { - logger.CallbackLog.Errorf("Get Request Body error: %+v", err) - problemDetail := models.ProblemDetails{ - Title: "System failure", - Status: http.StatusInternalServerError, - Detail: err.Error(), - Cause: "SYSTEM_FAILURE", - } - c.JSON(http.StatusInternalServerError, problemDetail) - return - } - - err = openapi.Deserialize(&n1MessageNotify, requestBody, "application/json") + err := c.ShouldBindWith(&n1MessageNotify, openapi.MultipartRelatedBinding{}) if err != nil { problemDetail := reqbody + err.Error() rsp := models.ProblemDetails{ diff --git a/internal/sbi/api_location.go b/internal/sbi/api_location.go index c5d455a..1f00fe9 100644 --- a/internal/sbi/api_location.go +++ b/internal/sbi/api_location.go @@ -29,15 +29,23 @@ func (s *Server) getLocationRoutes() []Route { }, }, { + Name: "ProvideLocationInfo", Method: http.MethodPost, Pattern: "/:ueContextId/provide-loc-info", APIFunc: s.HTTPProvideLocationInfo, }, { + Name: "ProvidePositioningInfo", Method: http.MethodPost, Pattern: "/:ueContextId/provide-pos-info", APIFunc: s.HTTPProvidePositioningInfo, }, + { + Name: "CancelLocation", + Method: http.MethodPost, + Pattern: "/:ueContextId/cancel-loc-info", + APIFunc: s.HTTPCancelLocation, + }, } } @@ -78,3 +86,7 @@ func (s *Server) HTTPProvidePositioningInfo(c *gin.Context) { logger.LocationLog.Warnf("Handle Provide Positioning Info is not implemented.") c.JSON(http.StatusNotImplemented, gin.H{}) } + +func (s *Server) HTTPCancelLocation(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} diff --git a/internal/sbi/api_mbsbroadcast.go b/internal/sbi/api_mbsbroadcast.go new file mode 100644 index 0000000..05ac370 --- /dev/null +++ b/internal/sbi/api_mbsbroadcast.go @@ -0,0 +1,49 @@ +package sbi + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *Server) getMbsBroadcastRoutes() []Route { + return []Route{ + { + Method: http.MethodGet, + Pattern: "/", + APIFunc: func(c *gin.Context) { + c.String(http.StatusOK, "Hello World!") + }, + }, + { + Name: "ContextCreate", + Method: http.MethodPost, + Pattern: "/mbs-contexts", + APIFunc: s.HTTPContextCreate, + }, + { + Name: "ContextUpdate", + Method: http.MethodPost, + Pattern: "/mbs-contexts/:mbsContextRef/update", + APIFunc: s.HTTPContextUpdate, + }, + { + Name: "ContextReleas", + Method: http.MethodDelete, + Pattern: "/mbs-contexts/:mbsContextRef", + APIFunc: s.HTTPContextRelease, + }, + } +} + +func (s *Server) HTTPContextCreate(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) HTTPContextUpdate(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} + +func (s *Server) HTTPContextRelease(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} diff --git a/internal/sbi/api_mbscommunication.go b/internal/sbi/api_mbscommunication.go new file mode 100644 index 0000000..4af620b --- /dev/null +++ b/internal/sbi/api_mbscommunication.go @@ -0,0 +1,29 @@ +package sbi + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *Server) getMbsCommunicationRoutes() []Route { + return []Route{ + { + Method: http.MethodGet, + Pattern: "/", + APIFunc: func(c *gin.Context) { + c.String(http.StatusOK, "Hello World!") + }, + }, + { + Name: "N2MessageTransfer", + Method: http.MethodPost, + Pattern: "/n2-messages/transfer", + APIFunc: s.HTTPN2MessageTransfer, + }, + } +} + +func (s *Server) HTTPN2MessageTransfer(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} diff --git a/internal/sbi/api_mt.go b/internal/sbi/api_mt.go index 54cbf8c..829d35c 100644 --- a/internal/sbi/api_mt.go +++ b/internal/sbi/api_mt.go @@ -18,15 +18,23 @@ func (s *Server) getMTRoutes() []Route { }, }, { + Name: "ProvideDomainSelectionInfo", Method: http.MethodGet, Pattern: "/ue-contexts/:ueContextId", APIFunc: s.HTTPProvideDomainSelectionInfo, }, { - Method: http.MethodPost, + Name: "EnableUeReachability", + Method: http.MethodPut, Pattern: "/ue-contexts/:ueContextId/ue-reachind", APIFunc: s.HTTPEnableUeReachability, }, + { + Name: "EnableGroupReachability", + Method: http.MethodPost, + Pattern: "/ue-contexts/enable-group-reachability", + APIFunc: s.HTTPEnableGroupReachability, + }, } } @@ -39,3 +47,7 @@ func (s *Server) HTTPEnableUeReachability(c *gin.Context) { logger.MtLog.Warnf("Handle Enable Ue Reachability is not implemented.") c.JSON(http.StatusNotImplemented, gin.H{}) } + +func (s *Server) HTTPEnableGroupReachability(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{}) +} diff --git a/internal/sbi/api_oam.go b/internal/sbi/api_oam.go index 1fcc9a0..c6ca5de 100644 --- a/internal/sbi/api_oam.go +++ b/internal/sbi/api_oam.go @@ -16,11 +16,13 @@ func (s *Server) getOAMRoutes() []Route { }, }, { + Name: "RegisteredUEContext", Method: http.MethodGet, Pattern: "/registered-ue-context", APIFunc: s.HTTPRegisteredUEContext, }, { + Name: "RegisteredUEContext", Method: http.MethodGet, Pattern: "/registered-ue-context/:supi", APIFunc: s.HTTPRegisteredUEContext, diff --git a/internal/sbi/consumer/amf_service.go b/internal/sbi/consumer/amf_service.go index e1acc76..68b8995 100644 --- a/internal/sbi/consumer/amf_service.go +++ b/internal/sbi/consumer/amf_service.go @@ -8,7 +8,7 @@ import ( "github.com/free5gc/amf/internal/logger" "github.com/free5gc/nas/nasMessage" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Namf_Communication" + Namf_Communication "github.com/free5gc/openapi/amf/Communication" "github.com/free5gc/openapi/models" ) @@ -129,18 +129,22 @@ func (s *namfService) BuildUeContextModel(ue *amf_context.AmfUe) (ueContext mode } func (s *namfService) buildAmPolicyReqTriggers( - triggers []models.RequestTrigger, -) (amPolicyReqTriggers []models.AmPolicyReqTrigger) { + triggers []models.PcfAmPolicyControlRequestTrigger, +) (amPolicyReqTriggers []models.PolicyReqTrigger) { for _, trigger := range triggers { switch trigger { - case models.RequestTrigger_LOC_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_LOCATION_CHANGE) - case models.RequestTrigger_PRA_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_PRA_CHANGE) - case models.RequestTrigger_SERV_AREA_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_SARI_CHANGE) - case models.RequestTrigger_RFSP_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_RFSP_INDEX_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_LOC_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_LOCATION_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_PRA_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_PRA_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_ALLOWED_NSSAI_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_ALLOWED_NSSAI_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_NWDAF_DATA_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_NWDAF_DATA_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_SMF_SELECT_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_SMF_SELECT_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_ACCESS_TYPE_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_ACCESS_TYPE_CHANGE) } } return @@ -157,31 +161,26 @@ func (s *namfService) CreateUEContextRequest(ue *amf_context.AmfUe, ueContextCre req := models.CreateUeContextRequest{ JsonData: &ueContextCreateData, } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NrfNfManagementNfType_AMF) if err != nil { return nil, nil, err } - res, httpResp, localErr := client.IndividualUeContextDocumentApi.CreateUEContext(ctx, ue.Guti, req) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("CreateUEContext response body cannot close: %+v", - rspCloseErr) - } - } - }() + + creatuectxreq := Namf_Communication.CreateUEContextRequest{ + UeContextId: &ue.Guti, + CreateUeContextRequest: &req, + } + + res, localErr := client.IndividualUeContextDocumentApi.CreateUEContext(ctx, &creatuectxreq) if localErr == nil { - ueContextCreatedData = res.JsonData + ueContextCreatedData = res.CreateUeContextResponse201.JsonData logger.ConsumerLog.Debugf("UeContextCreatedData: %+v", *ueContextCreatedData) - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return ueContextCreatedData, problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("%s: server no response", ue.TargetAmfUri) + if apiErr, ok := localErr.(openapi.GenericOpenAPIError); ok { + creatErr := apiErr.Model().(*Namf_Communication.CreateUEContextError) + return nil, &creatErr.ProblemDetails, nil + } + return nil, nil, localErr } return ueContextCreatedData, problemDetails, err } @@ -208,33 +207,37 @@ func (s *namfService) ReleaseUEContextRequest(ue *amf_context.AmfUe, ngapCause m ueContextRelease.Supi = ue.Supi ueContextRelease.UnauthenticatedSupi = true } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NrfNfManagementNfType_AMF) if err != nil { return nil, err } - httpResp, localErr := client.IndividualUeContextDocumentApi.ReleaseUEContext( - ctx, ueContextId, ueContextRelease) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("ReleaseUEContext response body cannot close: %+v", - rspCloseErr) + + ueCtxReleaseReq := Namf_Communication.ReleaseUEContextRequest{ + UeContextId: &ueContextId, + UeContextRelease: &ueContextRelease, + } + + _, err = client.IndividualUeContextDocumentApi.ReleaseUEContext( + ctx, &ueCtxReleaseReq) + if err != nil { + switch apiErr := err.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := apiErr.Model().(type) { + case Namf_Communication.ReleaseUEContextError: + return &errModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("server no response") } - }() - if localErr == nil { - return problemDetails, err - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("%s: server no response", ue.TargetAmfUri) } - return problemDetails, err + return nil, nil } func (s *namfService) UEContextTransferRequest( @@ -267,31 +270,37 @@ func (s *namfService) UEContextTransferRequest( // guti format is defined at TS 29.518 Table 6.1.3.2.2-1 5g-guti-[0-9]{5,6}[0-9a-fA-F]{14} ueContextId := fmt.Sprintf("5g-guti-%s", ue.Guti) - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NrfNfManagementNfType_AMF) if err != nil { return nil, nil, err } - res, httpResp, localErr := client.IndividualUeContextDocumentApi.UEContextTransfer(ctx, ueContextId, req) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("UEContextTransfer response body cannot close: %+v", - rspCloseErr) - } - } - }() + + ueCtxTransferReq := Namf_Communication.UEContextTransferRequest{ + UeContextId: &ueContextId, + UeContextTransferRequest: &req, + } + + res, localErr := client.IndividualUeContextDocumentApi.UEContextTransfer(ctx, &ueCtxTransferReq) if localErr == nil { - ueContextTransferRspData = res.JsonData + ueContextTransferRspData = res.UeContextTransferResponse200.JsonData logger.ConsumerLog.Debugf("UeContextTransferRspData: %+v", *ueContextTransferRspData) - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return ueContextTransferRspData, problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("%s: server no response", ue.TargetAmfUri) + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := apiErr.Model().(type) { + case Namf_Communication.UEContextTransferError: + problemDetails = &errModel.ProblemDetails + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(errModel.Error()) + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(apiErr.Error()) + default: + err = openapi.ReportError("server no response") + } } return ueContextTransferRspData, problemDetails, err } @@ -306,32 +315,37 @@ func (s *namfService) RegistrationStatusUpdate(ue *amf_context.AmfUe, request mo ueContextId := fmt.Sprintf("5g-guti-%s", ue.Guti) - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NfType_AMF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAMF_COMM, models.NrfNfManagementNfType_AMF) if err != nil { return regStatusTransferComplete, nil, err } - res, httpResp, localErr := client.IndividualUeContextDocumentApi. - RegistrationStatusUpdate(ctx, ueContextId, request) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("RegistrationStatusUpdate response body cannot close: %+v", - rspCloseErr) - } - } - }() + regStatusUpdateReq := Namf_Communication.RegistrationStatusUpdateRequest{ + UeContextId: &ueContextId, + UeRegStatusUpdateReqData: &request, + } + + res, localErr := client.IndividualUeContextDocumentApi. + RegistrationStatusUpdate(ctx, ®StatusUpdateReq) if localErr == nil { - regStatusTransferComplete = res.RegStatusTransferComplete - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return regStatusTransferComplete, problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem + regStatusTransferComplete = res.UeRegStatusUpdateRspData.RegStatusTransferComplete } else { - err = openapi.ReportError("%s: server no response", ue.TargetAmfUri) + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := apiErr.Model().(type) { + case Namf_Communication.RegistrationStatusUpdateError: + problemDetails = &errModel.ProblemDetails + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(errModel.Error()) + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(apiErr.Error()) + default: + err = openapi.ReportError("server no response") + } } return regStatusTransferComplete, problemDetails, err } diff --git a/internal/sbi/consumer/ausf_service.go b/internal/sbi/consumer/ausf_service.go index 402fb6d..ecaf769 100644 --- a/internal/sbi/consumer/ausf_service.go +++ b/internal/sbi/consumer/ausf_service.go @@ -8,13 +8,11 @@ import ( "strings" "sync" - "github.com/antihax/optional" - amf_context "github.com/free5gc/amf/internal/context" "github.com/free5gc/amf/internal/logger" "github.com/free5gc/nas/nasType" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nausf_UEAuthentication" + Nausf_UEAuthentication "github.com/free5gc/openapi/ausf/UEAuthentication" "github.com/free5gc/openapi/models" ) @@ -69,30 +67,35 @@ func (s *nausfService) SendUEAuthenticationAuthenticateRequest(ue *amf_context.A if resynchronizationInfo != nil { authInfo.ResynchronizationInfo = resynchronizationInfo } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAUSF_AUTH, models.NfType_AUSF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAUSF_AUTH, models.NrfNfManagementNfType_AUSF) if err != nil { return nil, nil, err } - ueAuthenticationCtx, httpResponse, err := client.DefaultApi.UeAuthenticationsPost(ctx, authInfo) - defer func() { - if httpResponse != nil { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("UeAuthenticationsPost response body cannot close: %+v", - rspCloseErr) + authReq := Nausf_UEAuthentication.UeAuthenticationsPostRequest{ + AuthenticationInfo: &authInfo, + } + + res, localErr := client.DefaultApi.UeAuthenticationsPost(ctx, &authReq) + if localErr == nil { + return &res.UeAuthenticationCtx, nil, nil + } else { + switch errType := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nausf_UEAuthentication.UeAuthenticationsPostError: + return nil, &errModel.ProblemDetails, localErr + case error: + return nil, openapi.ProblemDetailsSystemFailure(errModel.Error()), nil + default: + return nil, nil, openapi.ReportError("openapi error") } + case error: + return nil, openapi.ProblemDetailsSystemFailure(errType.Error()), err + default: + return nil, nil, openapi.ReportError("server no response") } - }() - if err == nil { - return &ueAuthenticationCtx, nil, nil - } else if httpResponse != nil { - if httpResponse.Status != err.Error() { - return nil, nil, err - } - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return nil, &problem, nil - } else { - return nil, nil, openapi.ReportError("server no response") } } @@ -100,7 +103,11 @@ func (s *nausfService) SendAuth5gAkaConfirmRequest(ue *amf_context.AmfUe, resSta *models.ConfirmationDataResponse, *models.ProblemDetails, error, ) { var ausfUri string - confirmUri, err := url.Parse(ue.AuthenticationCtx.Links["5g-aka"].Href) + var confirmUri *url.URL + var err error + if len(ue.AuthenticationCtx.Links["5g-aka"]) > 0 { + confirmUri, err = url.Parse(ue.AuthenticationCtx.Links["5g-aka"][0].Href) + } if err != nil { return nil, nil, err } else { @@ -112,12 +119,7 @@ func (s *nausfService) SendAuth5gAkaConfirmRequest(ue *amf_context.AmfUe, resSta return nil, nil, openapi.ReportError("ausf not found") } - confirmData := &Nausf_UEAuthentication.UeAuthenticationsAuthCtxId5gAkaConfirmationPutParamOpts{ - ConfirmationData: optional.NewInterface(models.ConfirmationData{ - ResStar: resStar, - }), - } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAUSF_AUTH, models.NfType_AUSF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAUSF_AUTH, models.NrfNfManagementNfType_AUSF) if err != nil { return nil, nil, err } @@ -132,37 +134,44 @@ func (s *nausfService) SendAuth5gAkaConfirmRequest(ue *amf_context.AmfUe, resSta return nil, nil, fmt.Errorf("authctxId is nil") } - confirmResult, httpResponse, err := client.DefaultApi.UeAuthenticationsAuthCtxId5gAkaConfirmationPut( - ctx, authctxId, confirmData) - defer func() { - if httpResponse != nil { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("UeAuthenticationsAuthCtxId5gAkaConfirmationPut response body cannot close: %+v", - rspCloseErr) + confirmData := &Nausf_UEAuthentication.UeAuthenticationsAuthCtxId5gAkaConfirmationPutRequest{ + AuthCtxId: &authctxId, + ConfirmationData: &models.ConfirmationData{ + ResStar: resStar, + }, + } + confirmResult, localErr := client.DefaultApi.UeAuthenticationsAuthCtxId5gAkaConfirmationPut( + ctx, confirmData) + if localErr == nil { + return &confirmResult.ConfirmationDataResponse, nil, nil + } else { + switch err := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := err.Model().(type) { + case Nausf_UEAuthentication.UeAuthenticationsAuthCtxId5gAkaConfirmationPutError: + return nil, &errModel.ProblemDetails, localErr + case error: + return nil, openapi.ProblemDetailsSystemFailure(errModel.Error()), nil + default: + return nil, nil, openapi.ReportError("openapi error") } + case error: + return nil, openapi.ProblemDetailsSystemFailure(err.Error()), nil + default: + return nil, nil, openapi.ReportError("server no response") } - }() - if err == nil { - return &confirmResult, nil, nil - } else if httpResponse != nil { - if httpResponse.Status != err.Error() { - return nil, nil, err - } - switch httpResponse.StatusCode { - case 400, 500: - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return nil, &problem, nil - } - return nil, nil, nil - } else { - return nil, nil, openapi.ReportError("server no response") } } func (s *nausfService) SendEapAuthConfirmRequest(ue *amf_context.AmfUe, eapMsg nasType.EAPMessage) ( response *models.EapSession, problemDetails *models.ProblemDetails, err1 error, ) { - confirmUri, err := url.Parse(ue.AuthenticationCtx.Links["eap-session"].Href) + var confirmUri *url.URL + var err error + if len(ue.AuthenticationCtx.Links["eap-session"]) > 0 { + confirmUri, err = url.Parse(ue.AuthenticationCtx.Links["eap-session"][0].Href) + } if err != nil { logger.ConsumerLog.Errorf("url Parse failed: %+v", err) } @@ -173,16 +182,6 @@ func (s *nausfService) SendEapAuthConfirmRequest(ue *amf_context.AmfUe, eapMsg n return nil, nil, openapi.ReportError("ausf not found") } - eapSessionReq := &Nausf_UEAuthentication.EapAuthMethodParamOpts{ - EapSession: optional.NewInterface(models.EapSession{ - EapPayload: base64.StdEncoding.EncodeToString(eapMsg.GetEAPMessage()), - }), - } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAUSF_AUTH, models.NfType_AUSF) - if err != nil { - return nil, nil, err - } - // confirmUri.RequestURI() = "/nausf-auth/v1/ue-authentications/{authctxId}/eap-session" // splituri = ["","nausf-auth","ue-authentications",{authctxId},"eap-session"] // authctxId = {authctxId} @@ -194,30 +193,40 @@ func (s *nausfService) SendEapAuthConfirmRequest(ue *amf_context.AmfUe, eapMsg n return nil, nil, fmt.Errorf("authctxId is nil") } - eapSession, httpResponse, err := client.DefaultApi.EapAuthMethod(ctx, authctxId, eapSessionReq) - defer func() { - if httpResponse != nil { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("EapAuthMethod response body cannot close: %+v", - rspCloseErr) + eapSessionReq := Nausf_UEAuthentication.EapAuthMethodRequest{ + AuthCtxId: &authctxId, + EapSession: &models.EapSession{ + EapPayload: base64.StdEncoding.EncodeToString(eapMsg.GetEAPMessage()), + }, + } + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NAUSF_AUTH, models.NrfNfManagementNfType_AUSF) + if err != nil { + return nil, nil, err + } + + eapSession, localErr := client.DefaultApi.EapAuthMethod(ctx, &eapSessionReq) + + if localErr == nil { + response = &eapSession.EapSession + } else { + err = localErr + switch errType := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nausf_UEAuthentication.EapAuthMethodError: + problemDetails = &errModel.ProblemDetails + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(errModel.Error()) + default: + err = openapi.ReportError("openapi error") } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(errType.Error()) + default: + err = openapi.ReportError("server no response") } - }() - if err == nil { - response = &eapSession - } else if httpResponse != nil { - if httpResponse.Status != err.Error() { - err1 = err - return response, problemDetails, err1 - } - switch httpResponse.StatusCode { - case 400, 500: - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } - } else { - err1 = openapi.ReportError("server no response") } - return response, problemDetails, err1 + return response, problemDetails, err } diff --git a/internal/sbi/consumer/consumer.go b/internal/sbi/consumer/consumer.go index 7dfb4d3..ab0b962 100644 --- a/internal/sbi/consumer/consumer.go +++ b/internal/sbi/consumer/consumer.go @@ -2,15 +2,15 @@ package consumer import ( "github.com/free5gc/amf/pkg/app" - "github.com/free5gc/openapi/Namf_Communication" - "github.com/free5gc/openapi/Nausf_UEAuthentication" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/Nnrf_NFManagement" - "github.com/free5gc/openapi/Nnssf_NSSelection" - "github.com/free5gc/openapi/Npcf_AMPolicy" - "github.com/free5gc/openapi/Nsmf_PDUSession" - "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" - "github.com/free5gc/openapi/Nudm_UEContextManagement" + Namf_Communication "github.com/free5gc/openapi/amf/Communication" + Nausf_UEAuthentication "github.com/free5gc/openapi/ausf/UEAuthentication" + Nnrf_NFDiscovery "github.com/free5gc/openapi/nrf/NFDiscovery" + Nnrf_NFManagement "github.com/free5gc/openapi/nrf/NFManagement" + Nnssf_NSSelection "github.com/free5gc/openapi/nssf/NSSelection" + Npcf_AMPolicy "github.com/free5gc/openapi/pcf/AMPolicyControl" + Nsmf_PDUSession "github.com/free5gc/openapi/smf/PDUSession" + Nudm_SubscriberDataManagement "github.com/free5gc/openapi/udm/SubscriberDataManagement" + Nudm_UEContextManagement "github.com/free5gc/openapi/udm/UEContextManagement" ) var consumer *Consumer diff --git a/internal/sbi/consumer/nrf_service.go b/internal/sbi/consumer/nrf_service.go index ddf1bab..701d4dc 100644 --- a/internal/sbi/consumer/nrf_service.go +++ b/internal/sbi/consumer/nrf_service.go @@ -3,7 +3,6 @@ package consumer import ( "context" "fmt" - "net/http" "strings" "sync" "time" @@ -13,9 +12,9 @@ import ( "github.com/free5gc/amf/internal/util" "github.com/free5gc/amf/pkg/factory" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/Nnrf_NFManagement" "github.com/free5gc/openapi/models" + Nnrf_NFDiscovery "github.com/free5gc/openapi/nrf/NFDiscovery" + Nnrf_NFManagement "github.com/free5gc/openapi/nrf/NFManagement" ) type nnrfService struct { @@ -72,40 +71,35 @@ func (s *nnrfService) getNFDiscClient(uri string) *Nnrf_NFDiscovery.APIClient { return client } -func (s *nnrfService) SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfType, - param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts, +func (s *nnrfService) SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NrfNfManagementNfType, + param *Nnrf_NFDiscovery.SearchNFInstancesRequest, ) (*models.SearchResult, error) { // Set client and set url + param.TargetNfType = &targetNfType + param.RequesterNfType = &requestNfType client := s.getNFDiscClient(nrfUri) if client == nil { return nil, openapi.ReportError("nrf not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NfType_NRF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_DISC, models.NrfNfManagementNfType_NRF) if err != nil { return nil, err } - - result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, param) - if res != nil && res.StatusCode == http.StatusTemporaryRedirect { - return nil, fmt.Errorf("temporary Redirect For Non NRF Consumer") + res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, param) + var result *models.SearchResult + if err != nil { + logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err) } - if res == nil || res.Body == nil { - return &result, err + if res != nil { + result = &res.SearchResult } - defer func() { - if res != nil { - if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil { - err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr) - } - } - }() - return &result, err + return result, err } func (s *nnrfService) SearchUdmSdmInstance( - ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NfType, - param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts, + ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NrfNfManagementNfType, + param *Nnrf_NFDiscovery.SearchNFInstancesRequest, ) error { resp, localErr := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, param) if localErr != nil { @@ -114,9 +108,10 @@ func (s *nnrfService) SearchUdmSdmInstance( // select the first UDM_SDM, TODO: select base on other info var sdmUri string - for _, nfProfile := range resp.NfInstances { - ue.UdmId = nfProfile.NfInstanceId - sdmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_SDM, models.NfServiceStatus_REGISTERED) + for index := range resp.NfInstances { + ue.UdmId = resp.NfInstances[index].NfInstanceId + sdmUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NUDM_SDM, + models.NfServiceStatus_REGISTERED) if sdmUri != "" { break } @@ -131,8 +126,8 @@ func (s *nnrfService) SearchUdmSdmInstance( } func (s *nnrfService) SearchNssfNSSelectionInstance( - ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NfType, - param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts, + ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NrfNfManagementNfType, + param *Nnrf_NFDiscovery.SearchNFInstancesRequest, ) error { resp, localErr := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, param) if localErr != nil { @@ -141,9 +136,10 @@ func (s *nnrfService) SearchNssfNSSelectionInstance( // select the first NSSF, TODO: select base on other info var nssfUri string - for _, nfProfile := range resp.NfInstances { - ue.NssfId = nfProfile.NfInstanceId - nssfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NNSSF_NSSELECTION, models.NfServiceStatus_REGISTERED) + for index := range resp.NfInstances { + ue.NssfId = resp.NfInstances[index].NfInstanceId + nssfUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NNSSF_NSSELECTION, + models.NfServiceStatus_REGISTERED) if nssfUri != "" { break } @@ -156,7 +152,7 @@ func (s *nnrfService) SearchNssfNSSelectionInstance( } func (s *nnrfService) SearchAmfCommunicationInstance(ue *amf_context.AmfUe, nrfUri string, targetNfType, - requestNfType models.NfType, param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts, + requestNfType models.NrfNfManagementNfType, param *Nnrf_NFDiscovery.SearchNFInstancesRequest, ) (err error) { resp, localErr := s.SendSearchNFInstances(nrfUri, targetNfType, requestNfType, param) if localErr != nil { @@ -166,12 +162,13 @@ func (s *nnrfService) SearchAmfCommunicationInstance(ue *amf_context.AmfUe, nrfU // select the first AMF, TODO: select base on other info var amfUri string - for _, nfProfile := range resp.NfInstances { - if nfProfile.NfInstanceId == amf_context.GetSelf().NfId { + for index := range resp.NfInstances { + if resp.NfInstances[index].NfInstanceId == amf_context.GetSelf().NfId { continue } - ue.TargetAmfProfile = &nfProfile - amfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NAMF_COMM, models.NfServiceStatus_REGISTERED) + ue.TargetAmfProfile = &resp.NfInstances[index] + amfUri = util.SearchNFServiceUri(&resp.NfInstances[index], models.ServiceName_NAMF_COMM, + models.NfServiceStatus_REGISTERED) if amfUri != "" { break } @@ -183,20 +180,26 @@ func (s *nnrfService) SearchAmfCommunicationInstance(ue *amf_context.AmfUe, nrfU return } -func (s *nnrfService) BuildNFInstance(context *amf_context.AMFContext) (profile models.NfProfile, err error) { +func (s *nnrfService) BuildNFInstance(context *amf_context.AMFContext) ( + profile models.NrfNfManagementNfProfile, err error, +) { profile.NfInstanceId = context.NfId - profile.NfType = models.NfType_AMF - profile.NfStatus = models.NfStatus_REGISTERED + profile.NfType = models.NrfNfManagementNfType_AMF + profile.NfStatus = models.NrfNfManagementNfStatus_REGISTERED var plmns []models.PlmnId for _, plmnItem := range context.PlmnSupportList { plmns = append(plmns, *plmnItem.PlmnId) } if len(plmns) > 0 { - profile.PlmnList = &plmns + profile.PlmnList = plmns // TODO: change to Per Plmn Support Snssai List - profile.SNssais = &context.PlmnSupportList[0].SNssaiList + var SnssaiList []models.ExtSnssai + for _, snssaiItem := range context.PlmnSupportList[0].SNssaiList { + SnssaiList = append(SnssaiList, util.SnssaiModelsToExtSnssai(snssaiItem)) + } + profile.SNssais = SnssaiList } - amfInfo := models.AmfInfo{} + amfInfo := models.NrfNfManagementAmfInfo{} if len(context.ServedGuamiList) == 0 { err = fmt.Errorf("gumai List is Empty in AMF") return profile, err @@ -208,29 +211,29 @@ func (s *nnrfService) BuildNFInstance(context *amf_context.AMFContext) (profile } amfInfo.AmfRegionId = regionId amfInfo.AmfSetId = setId - amfInfo.GuamiList = &context.ServedGuamiList + amfInfo.GuamiList = context.ServedGuamiList if len(context.SupportTaiLists) == 0 { err = fmt.Errorf("SupportTaiList is Empty in AMF") return profile, err } - amfInfo.TaiList = &context.SupportTaiLists + amfInfo.TaiList = context.SupportTaiLists profile.AmfInfo = &amfInfo if context.RegisterIPv4 == "" { err = fmt.Errorf("AMF Address is empty") return profile, err } profile.Ipv4Addresses = append(profile.Ipv4Addresses, context.RegisterIPv4) - service := []models.NfService{} + service := []models.NrfNfManagementNfService{} for _, nfService := range context.NfService { service = append(service, nfService) } if len(service) > 0 { - profile.NfServices = &service + profile.NfServices = service } defaultNotificationSubscription := models.DefaultNotificationSubscription{ CallbackUri: fmt.Sprintf("%s"+factory.AmfCallbackResUriPrefix+"/n1-message-notify", context.GetIPv4Uri()), - NotificationType: models.NotificationType_N1_MESSAGES, + NotificationType: models.NrfNfManagementNotificationType_N1_MESSAGES, N1MessageClass: models.N1MessageClass__5_GMM, } profile.DefaultNotificationSubscriptions = append(profile.DefaultNotificationSubscriptions, @@ -238,7 +241,8 @@ func (s *nnrfService) BuildNFInstance(context *amf_context.AMFContext) (profile return profile, err } -func (s *nnrfService) SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfile) ( +func (s *nnrfService) SendRegisterNFInstance(ctx context.Context, nrfUri, nfInstanceId string, + profile *models.NrfNfManagementNfProfile) ( resouceNrfUri string, retrieveNfInstanceId string, err error, ) { // Set client and set url @@ -247,54 +251,53 @@ func (s *nnrfService) SendRegisterNFInstance(nrfUri, nfInstanceId string, profil return "", "", openapi.ReportError("nrf not found") } - var res *http.Response - var nf models.NfProfile - for { - nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile) - if err != nil || res == nil { - // TODO : add log - fmt.Println(fmt.Errorf("AMF register to NRF Error[%s]", err.Error())) - time.Sleep(2 * time.Second) - continue - } - defer func() { - if res != nil { - if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil { - err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr) - } - } - }() - status := res.StatusCode - if status == http.StatusOK { - // NFUpdate - break - } else if status == http.StatusCreated { - // NFRegister - resourceUri := res.Header.Get("Location") - index := strings.Index(resourceUri, "/nnrf-nfm/") - if index >= 0 { - resouceNrfUri = resourceUri[:index] + var res *Nnrf_NFManagement.RegisterNFInstanceResponse + var nf models.NrfNfManagementNfProfile + registerNFInstanceRequest := &Nnrf_NFManagement.RegisterNFInstanceRequest{ + NfInstanceID: &nfInstanceId, + NrfNfManagementNfProfile: profile, + } + finish := false + for !finish { + select { + case <-ctx.Done(): + return "", "", fmt.Errorf("context done") + default: + res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(ctx, registerNFInstanceRequest) + if err != nil || res == nil { + // TODO : add log + logger.ConsumerLog.Errorf("AMF register to NRF Error[%s]", err.Error()) + time.Sleep(2 * time.Second) + continue } - // resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] - retrieveNfInstanceId = resourceUri[strings.LastIndex(resourceUri, "/")+1:] + if res.Location == "" { + // NFUpdate + finish = true + } else { + // NFRegister + resourceUri := res.Location + nf = res.NrfNfManagementNfProfile + index := strings.Index(resourceUri, "/nnrf-nfm/") + if index >= 0 { + resouceNrfUri = resourceUri[:index] + } + // resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] + retrieveNfInstanceId = resourceUri[strings.LastIndex(resourceUri, "/")+1:] - oauth2 := false - if nf.CustomInfo != nil { - v, ok := nf.CustomInfo["oauth2"].(bool) - if ok { - oauth2 = v - logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) + oauth2 := false + if nf.CustomInfo != nil { + v, ok := nf.CustomInfo["oauth2"].(bool) + if ok { + oauth2 = v + logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) + } } + amf_context.GetSelf().OAuth2Required = oauth2 + if oauth2 && amf_context.GetSelf().NrfCertPem == "" { + logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") + } + finish = true } - amf_context.GetSelf().OAuth2Required = oauth2 - if oauth2 && amf_context.GetSelf().NrfCertPem == "" { - logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") - } - - break - } else { - fmt.Println(fmt.Errorf("handler returned wrong status code %d", status)) - fmt.Println(fmt.Errorf("NRF return wrong status code %d", status)) } } return resouceNrfUri, retrieveNfInstanceId, err @@ -309,29 +312,34 @@ func (s *nnrfService) SendDeregisterNFInstance() (problemDetails *models.Problem return nil, openapi.ReportError("nrf not found") } - ctx, pd, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF) + ctx, pd, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NrfNfManagementNfType_NRF) if err != nil { return pd, err } - var res *http.Response + request := &Nnrf_NFManagement.DeregisterNFInstanceRequest{ + NfInstanceID: &amfContext.NfId, + } - res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, amfContext.NfId) - if err == nil { - return problemDetails, err - } else if res != nil { - defer func() { - if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil { - err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr) + _, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, request) + if err != nil { + switch apiErr := err.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := apiErr.Model().(type) { + case Nnrf_NFManagement.DeregisterNFInstanceError: + problemDetails = &errModel.ProblemDetails + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(errModel.Error()) + default: + err = openapi.ReportError("openapi error") } - }() - if res.Status != err.Error() { - return problemDetails, err + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(apiErr.Error()) + default: + err = openapi.ReportError("server no response") } - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("server no response") } + return problemDetails, err } diff --git a/internal/sbi/consumer/nssf_service.go b/internal/sbi/consumer/nssf_service.go index dac7f96..4d4c2a8 100644 --- a/internal/sbi/consumer/nssf_service.go +++ b/internal/sbi/consumer/nssf_service.go @@ -1,16 +1,12 @@ package consumer import ( - "encoding/json" "sync" - "github.com/antihax/optional" - amf_context "github.com/free5gc/amf/internal/context" - "github.com/free5gc/amf/internal/logger" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnssf_NSSelection" "github.com/free5gc/openapi/models" + Nnssf_NSSelection "github.com/free5gc/openapi/nssf/NSSelection" ) type nssfService struct { @@ -52,7 +48,8 @@ func (s *nssfService) NSSelectionGetForRegistration(ue *amf_context.AmfUe, reque } amfSelf := amf_context.GetSelf() - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNSSF_NSSELECTION, models.NfType_NSSF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNSSF_NSSELECTION, + models.NrfNfManagementNfType_NSSF) if err != nil { return nil, err } @@ -67,45 +64,42 @@ func (s *nssfService) NSSelectionGetForRegistration(ue *amf_context.AmfUe, reque } } - var paramOpt Nnssf_NSSelection.NSSelectionGetParamOpts - if e, errsliceinfo := json.Marshal(sliceInfo); errsliceinfo != nil { - logger.ConsumerLog.Warnf("slice json marshal failed: %+v", errsliceinfo) - } else { - tai, taierr := json.Marshal(ue.Tai) - if taierr != nil { - logger.ConsumerLog.Warnf("tai json marshal failed: %+v", taierr) - } - paramOpt = Nnssf_NSSelection.NSSelectionGetParamOpts{ - SliceInfoRequestForRegistration: optional.NewInterface(string(e)), - Tai: optional.NewInterface(string(tai)), // TS 29.531 R15.3 6.1.3.2.3.1 - } + var paramOpt Nnssf_NSSelection.NSSelectionGetRequest + + testNfType := models.NrfNfManagementNfType_AMF + + paramOpt = Nnssf_NSSelection.NSSelectionGetRequest{ + NfType: &testNfType, + NfId: &amfSelf.NfId, + SliceInfoRequestForRegistration: &sliceInfo, + Tai: &ue.Tai, // TS 29.531 R15.3 6.1.3.2.3.1 } - res, httpResp, localErr := client.NetworkSliceInformationDocumentApi.NSSelectionGet(ctx, - models.NfType_AMF, amfSelf.NfId, ¶mOpt) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("NSSelectionGet response body cannot close: %+v", - rspCloseErr) - } - } - }() + res, localErr := client.NetworkSliceInformationDocumentApi.NSSelectionGet(ctx, + ¶mOpt) if localErr == nil { - ue.NetworkSliceInfo = &res - for _, allowedNssai := range res.AllowedNssaiList { + ue.NetworkSliceInfo = &res.AuthorizedNetworkSliceInfo + for _, allowedNssai := range res.AuthorizedNetworkSliceInfo.AllowedNssaiList { ue.AllowedNssai[allowedNssai.AccessType] = allowedNssai.AllowedSnssaiList } - ue.ConfiguredNssai = res.ConfiguredNssai - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - errlocal := localErr - return nil, errlocal - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return &problem, nil + ue.ConfiguredNssai = res.AuthorizedNetworkSliceInfo.ConfiguredNssai } else { - return nil, openapi.ReportError("NSSF No Response") + switch apiErr := err.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := apiErr.Model().(type) { + case Nnssf_NSSelection.NSSelectionGetError: + return &errModel.ProblemDetails, localErr + case error: + return openapi.ProblemDetailsSystemFailure(errModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } } return nil, nil @@ -125,42 +119,40 @@ func (s *nssfService) NSSelectionGetForPduSession(ue *amf_context.AmfUe, snssai RoamingIndication: models.RoamingIndication_NON_ROAMING, // not support roaming } - e, err := json.Marshal(sliceInfoForPduSession) - if err != nil { - logger.ConsumerLog.Warnf("slice json marshal failed: %+v", err) - } - tai, taierr := json.Marshal(ue.Tai) - if taierr != nil { - logger.ConsumerLog.Warnf("tai json marshal failed: %+v", taierr) - } - paramOpt := Nnssf_NSSelection.NSSelectionGetParamOpts{ - SliceInfoRequestForPduSession: optional.NewInterface(string(e)), - Tai: optional.NewInterface(string(tai)), // TS 29.531 R15.3 6.1.3.2.3.1 + testNfType := models.NrfNfManagementNfType_AMF + + paramOpt := Nnssf_NSSelection.NSSelectionGetRequest{ + NfType: &testNfType, + NfId: &amfSelf.NfId, + SliceInfoRequestForPduSession: &sliceInfoForPduSession, + Tai: &ue.Tai, // TS 29.531 R15.3 6.1.3.2.3.1 } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNSSF_NSSELECTION, models.NfType_NSSF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NNSSF_NSSELECTION, + models.NrfNfManagementNfType_NSSF) if err != nil { return nil, nil, err } - res, httpResp, localErr := client.NetworkSliceInformationDocumentApi.NSSelectionGet(ctx, - models.NfType_AMF, amfSelf.NfId, ¶mOpt) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("NSSelectionGet response body cannot close: %+v", - rspCloseErr) - } - } - }() + res, localErr := client.NetworkSliceInformationDocumentApi.NSSelectionGet(ctx, ¶mOpt) + if localErr == nil { - return &res, nil, nil - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - return nil, nil, localErr - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return nil, &problem, nil + return &res.AuthorizedNetworkSliceInfo, nil, nil } else { - return nil, nil, openapi.ReportError("NSSF No Response") + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := apiErr.Model().(type) { + case Nnssf_NSSelection.NSSelectionGetError: + return nil, &errModel.ProblemDetails, localErr + case error: + return nil, openapi.ProblemDetailsSystemFailure(errModel.Error()), nil + default: + return nil, nil, openapi.ReportError("openapi error") + } + case error: + return nil, openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, nil, openapi.ReportError("server no response") + } } } diff --git a/internal/sbi/consumer/pcf_service.go b/internal/sbi/consumer/pcf_service.go index a22c4b2..1aa159e 100644 --- a/internal/sbi/consumer/pcf_service.go +++ b/internal/sbi/consumer/pcf_service.go @@ -8,8 +8,8 @@ import ( "github.com/free5gc/amf/internal/logger" "github.com/free5gc/amf/pkg/factory" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Npcf_AMPolicy" "github.com/free5gc/openapi/models" + Npcf_AMPolicy "github.com/free5gc/openapi/pcf/AMPolicyControl" ) type npcfService struct { @@ -50,38 +50,36 @@ func (s *npcfService) AMPolicyControlCreate( return nil, openapi.ReportError("pcf not found") } amfSelf := amf_context.GetSelf() - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, + models.NrfNfManagementNfType_PCF) if err != nil { return nil, err } - policyAssociationRequest := models.PolicyAssociationRequest{ + policyAssociationRequest := models.PcfAmPolicyControlPolicyAssociationRequest{ NotificationUri: amfSelf.GetIPv4Uri() + factory.AmfCallbackResUriPrefix + "/am-policy/", Supi: ue.Supi, Pei: ue.Pei, Gpsi: ue.Gpsi, AccessType: anType, - ServingPlmn: &models.NetworkId{ + ServingPlmn: &models.PlmnIdNid{ Mcc: ue.PlmnId.Mcc, Mnc: ue.PlmnId.Mnc, }, Guami: &amfSelf.ServedGuamiList[0], } + var policyAssociationreq Npcf_AMPolicy.CreateIndividualAMPolicyAssociationRequest + + policyAssociationreq.SetPcfAmPolicyControlPolicyAssociationRequest(policyAssociationRequest) if ue.AccessAndMobilitySubscriptionData != nil { policyAssociationRequest.Rfsp = ue.AccessAndMobilitySubscriptionData.RfspIndex } - res, httpResp, localErr := client.DefaultApi.PoliciesPost(ctx, policyAssociationRequest) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("PoliciesPost response body cannot close: %+v", - rspCloseErr) - } - } - }() + + res, localErr := client.AMPolicyAssociationsCollectionApi. + CreateIndividualAMPolicyAssociation(ctx, &policyAssociationreq) if localErr == nil { - locationHeader := httpResp.Header.Get("Location") + locationHeader := res.Location logger.ConsumerLog.Debugf("location header: %+v", locationHeader) ue.AmPolicyUri = locationHeader @@ -89,11 +87,11 @@ func (s *npcfService) AMPolicyControlCreate( match := re.FindStringSubmatch(locationHeader) ue.PolicyAssociationId = match[0][10:] - ue.AmPolicyAssociation = &res + ue.AmPolicyAssociation = &res.PcfAmPolicyControlPolicyAssociation - if res.Triggers != nil { - for _, trigger := range res.Triggers { - if trigger == models.RequestTrigger_LOC_CH { + if res.PcfAmPolicyControlPolicyAssociation.Triggers != nil { + for _, trigger := range res.PcfAmPolicyControlPolicyAssociation.Triggers { + if trigger == models.PcfAmPolicyControlRequestTrigger_LOC_CH { ue.RequestTriggerLocationChange = true } // if trigger == models.RequestTrigger_PRA_CH { @@ -104,70 +102,84 @@ func (s *npcfService) AMPolicyControlCreate( logger.ConsumerLog.Debugf("UE AM Policy Association ID: %s", ue.PolicyAssociationId) logger.ConsumerLog.Debugf("AmPolicyAssociation: %+v", ue.AmPolicyAssociation) - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - return nil, localErr - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return &problem, nil } else { - return nil, openapi.ReportError("server no response") + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Npcf_AMPolicy.CreateIndividualAMPolicyAssociationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } } return nil, nil } func (s *npcfService) AMPolicyControlUpdate( - ue *amf_context.AmfUe, updateRequest models.PolicyAssociationUpdateRequest, + ue *amf_context.AmfUe, updateRequest models.PcfAmPolicyControlPolicyAssociationUpdateRequest, ) (problemDetails *models.ProblemDetails, err error) { client := s.getAMPolicyClient(ue.PcfUri) if client == nil { return nil, openapi.ReportError("pcf not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, + models.NrfNfManagementNfType_PCF) if err != nil { return nil, err } - res, httpResp, localErr := client.DefaultApi.PoliciesPolAssoIdUpdatePost( - ctx, ue.PolicyAssociationId, updateRequest) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("PoliciesPolAssoIdUpdatePost response body cannot close: %+v", - rspCloseErr) - } - } - }() + var policyUpdateReq Npcf_AMPolicy.ReportObservedEventTriggersForIndividualAMPolicyAssociationRequest + + policyUpdateReq.SetPolAssoId(ue.PolicyAssociationId) + policyUpdateReq.SetPcfAmPolicyControlPolicyAssociationUpdateRequest(updateRequest) + + res, localErr := client.IndividualAMPolicyAssociationDocumentApi. + ReportObservedEventTriggersForIndividualAMPolicyAssociation(ctx, &policyUpdateReq) if localErr == nil { - if res.ServAreaRes != nil { - ue.AmPolicyAssociation.ServAreaRes = res.ServAreaRes + if res.PcfAmPolicyControlPolicyUpdate.ServAreaRes != nil { + ue.AmPolicyAssociation.ServAreaRes = res.PcfAmPolicyControlPolicyUpdate.ServAreaRes } - if res.Rfsp != 0 { - ue.AmPolicyAssociation.Rfsp = res.Rfsp + if res.PcfAmPolicyControlPolicyUpdate.Rfsp != 0 { + ue.AmPolicyAssociation.Rfsp = res.PcfAmPolicyControlPolicyUpdate.Rfsp } - ue.AmPolicyAssociation.Triggers = res.Triggers + ue.AmPolicyAssociation.Triggers = res.PcfAmPolicyControlPolicyUpdate.Triggers ue.RequestTriggerLocationChange = false - for _, trigger := range res.Triggers { - if trigger == models.RequestTrigger_LOC_CH { + for _, trigger := range res.PcfAmPolicyControlPolicyUpdate.Triggers { + if trigger == models.PcfAmPolicyControlRequestTrigger_LOC_CH { ue.RequestTriggerLocationChange = true } // if trigger == models.RequestTrigger_PRA_CH { // TODO: Presence Reporting Area handling (TS 23.503 6.1.2.5, TS 23.501 5.6.11) // } } - return problemDetails, err - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("server no response") + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Npcf_AMPolicy.ReportObservedEventTriggersForIndividualAMPolicyAssociationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + err = openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + err = openapi.ReportError("server no response") + } } - return problemDetails, err + return nil, err } func (s *npcfService) AMPolicyControlDelete(ue *amf_context.AmfUe) (problemDetails *models.ProblemDetails, err error) { @@ -176,31 +188,35 @@ func (s *npcfService) AMPolicyControlDelete(ue *amf_context.AmfUe) (problemDetai return nil, openapi.ReportError("pcf not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfType_PCF) - if err != nil { - return nil, err + ctx, _, ctxErr := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NPCF_AM_POLICY_CONTROL, + models.NrfNfManagementNfType_PCF) + if ctxErr != nil { + return nil, ctxErr } - httpResp, localErr := client.DefaultApi.PoliciesPolAssoIdDelete(ctx, ue.PolicyAssociationId) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("PoliciesPolAssoIdDelete response body cannot close: %+v", - rspCloseErr) - } - } - }() - if localErr == nil { + var deleteReq Npcf_AMPolicy.DeleteIndividualAMPolicyAssociationRequest + deleteReq.SetPolAssoId(ue.PolicyAssociationId) + + _, err = client.IndividualAMPolicyAssociationDocumentApi.DeleteIndividualAMPolicyAssociation(ctx, &deleteReq) + if err == nil { ue.RemoveAmPolicyAssociation() - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return nil, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("server no response") + switch apiErr := err.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Npcf_AMPolicy.DeleteIndividualAMPolicyAssociationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + err = openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + err = openapi.ReportError("server no response") + } } - return problemDetails, err + return nil, err } diff --git a/internal/sbi/consumer/smf_service.go b/internal/sbi/consumer/smf_service.go index 26c465d..5a7073c 100644 --- a/internal/sbi/consumer/smf_service.go +++ b/internal/sbi/consumer/smf_service.go @@ -7,17 +7,14 @@ import ( "sync" "time" - "github.com/antihax/optional" - amf_context "github.com/free5gc/amf/internal/context" - "github.com/free5gc/amf/internal/logger" "github.com/free5gc/amf/internal/util" "github.com/free5gc/amf/pkg/factory" "github.com/free5gc/nas/nasMessage" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nnrf_NFDiscovery" - "github.com/free5gc/openapi/Nsmf_PDUSession" "github.com/free5gc/openapi/models" + Nnrf_NFDiscovery "github.com/free5gc/openapi/nrf/NFDiscovery" + Nsmf_PDUSession "github.com/free5gc/openapi/smf/PDUSession" ) var n2sminfocon = "N2SmInfo" @@ -73,8 +70,9 @@ func (s *nsmfService) SelectSmf( if ue.NssfUri == "" { // TODO: Set a timeout of NSSF Selection or will starvation here for { - if err := s.consumer.SearchNssfNSSelectionInstance(ue, nrfUri, models.NfType_NSSF, - models.NfType_AMF, nil); err != nil { + searchReq := Nnrf_NFDiscovery.SearchNFInstancesRequest{} + if err := s.consumer.SearchNssfNSSelectionInstance(ue, nrfUri, models.NrfNfManagementNfType_NSSF, + models.NrfNfManagementNfType_AMF, &searchReq); err != nil { ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", err) time.Sleep(2 * time.Second) } else { @@ -111,21 +109,22 @@ func (s *nsmfService) SelectSmf( } } - param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ - ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NSMF_PDUSESSION}), - Dnn: optional.NewString(dnn), - Snssais: optional.NewInterface(openapi.MarshToJsonString([]models.Snssai{snssai})), + param := Nnrf_NFDiscovery.SearchNFInstancesRequest{ + ServiceNames: []models.ServiceName{models.ServiceName_NSMF_PDUSESSION}, + Dnn: &dnn, + Snssais: []models.Snssai{snssai}, } if ue.PlmnId.Mcc != "" { - param.TargetPlmnList = optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId)) + param.TargetPlmnList = append(param.TargetPlmnList, ue.PlmnId) } if amf_context.GetSelf().Locality != "" { - param.PreferredLocality = optional.NewString(amf_context.GetSelf().Locality) + param.PreferredLocality = &amf_context.GetSelf().Locality } ue.GmmLog.Debugf("Search SMF from NRF[%s]", nrfUri) - result, err := s.consumer.SendSearchNFInstances(nrfUri, models.NfType_SMF, models.NfType_AMF, ¶m) + result, err := s.consumer.SendSearchNFInstances(nrfUri, models.NrfNfManagementNfType_SMF, + models.NrfNfManagementNfType_AMF, ¶m) if err != nil { return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err } @@ -136,8 +135,9 @@ func (s *nsmfService) SelectSmf( } // select the first SMF, TODO: select base on other info - for _, nfProfile := range result.NfInstances { - smfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NSMF_PDUSESSION, models.NfServiceStatus_REGISTERED) + for index := range result.NfInstances { + smfUri = util.SearchNFServiceUri(&result.NfInstances[index], models.ServiceName_NSMF_PDUSESSION, + models.NfServiceStatus_REGISTERED) if smfUri != "" { break } @@ -149,60 +149,57 @@ func (s *nsmfService) SelectSmf( func (s *nsmfService) SendCreateSmContextRequest(ue *amf_context.AmfUe, smContext *amf_context.SmContext, requestType *models.RequestType, nasPdu []byte) ( - response *models.PostSmContextsResponse, smContextRef string, errorResponse *models.PostSmContextsErrorResponse, + smContextRef string, errorResponse *models.PostSmContextsError, problemDetail *models.ProblemDetails, err1 error, ) { smContextCreateData := s.buildCreateSmContextRequest(ue, smContext, nil) - postSmContextsRequest := models.PostSmContextsRequest{ - JsonData: &smContextCreateData, - BinaryDataN1SmMessage: nasPdu, + postSmContextsRequest := Nsmf_PDUSession.PostSmContextsRequest{ + PostSmContextsRequest: &models.PostSmContextsRequest{ + JsonData: &smContextCreateData, + BinaryDataN1SmMessage: nasPdu, + }, } client := s.getPDUSessionClient(smContext.SmfUri()) if client == nil { - return nil, "", nil, nil, openapi.ReportError("smf not found") + return "", nil, nil, openapi.ReportError("smf not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NSMF_PDUSESSION, models.NfType_SMF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NSMF_PDUSESSION, models.NrfNfManagementNfType_SMF) if err != nil { - return nil, "", nil, nil, err - } - postSmContextReponse, httpResponse, err := client.SMContextsCollectionApi. - PostSmContexts(ctx, postSmContextsRequest) - defer func() { - if httpResponse != nil { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("PostSmContexts response body cannot close: %+v", - rspCloseErr) + return "", nil, nil, err + } + postSmContextReponse, localErr := client.SMContextsCollectionApi. + PostSmContexts(ctx, &postSmContextsRequest) + if localErr == nil { + smContextRef = postSmContextReponse.Location + } else { + err1 = localErr + switch errType := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nsmf_PDUSession.PostSmContextsError: + problemDetail = &errModel.ProblemDetails + errorResponse = &errModel.PostSmContextsError + case error: + err1 = errModel + default: + err1 = openapi.ReportError("openapi error") } + case error: + problemDetail = openapi.ProblemDetailsSystemFailure(err1.Error()) + default: + err1 = openapi.ReportError("server no response") } - }() - if err == nil { - response = &postSmContextReponse - smContextRef = httpResponse.Header.Get("Location") - } else if httpResponse != nil { - if httpResponse.Status != err.Error() { - err1 = err - return response, smContextRef, errorResponse, problemDetail, err1 - } - switch httpResponse.StatusCode { - case 400, 403, 404, 500, 503, 504: - errResponse := err.(openapi.GenericOpenAPIError).Model().(models.PostSmContextsErrorResponse) - errorResponse = &errResponse - case 411, 413, 415, 429: - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetail = &problem - } - } else { - err1 = openapi.ReportError("server no response") } - return response, smContextRef, errorResponse, problemDetail, err1 + return smContextRef, errorResponse, problemDetail, err1 } func (s *nsmfService) buildCreateSmContextRequest(ue *amf_context.AmfUe, smContext *amf_context.SmContext, requestType *models.RequestType, -) (smContextCreateData models.SmContextCreateData) { +) (smContextCreateData models.SmfPduSessionSmContextCreateData) { context := amf_context.GetSelf() smContextCreateData.Supi = ue.Supi smContextCreateData.UnauthenticatedSupi = ue.UnauthenticatedSupi @@ -251,9 +248,9 @@ func (s *nsmfService) buildCreateSmContextRequest(ue *amf_context.AmfUe, smConte func (s *nsmfService) SendUpdateSmContextActivateUpCnxState( ue *amf_context.AmfUe, smContext *amf_context.SmContext, accessType models.AccessType) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.UpCnxState = models.UpCnxState_ACTIVATING if !amf_context.CompareUserLocation(ue.Location, smContext.UserLocation()) { updateData.UeLocation = &ue.Location @@ -266,14 +263,14 @@ func (s *nsmfService) SendUpdateSmContextActivateUpCnxState( updateData.PresenceInLadn = models.PresenceState_IN_AREA } } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, nil) } func (s *nsmfService) SendUpdateSmContextDeactivateUpCnxState(ue *amf_context.AmfUe, smContext *amf_context.SmContext, cause amf_context.CauseAll) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.UpCnxState = models.UpCnxState_DEACTIVATED updateData.UeLocation = &ue.Location if cause.Cause != nil { @@ -285,35 +282,35 @@ func (s *nsmfService) SendUpdateSmContextDeactivateUpCnxState(ue *amf_context.Am if cause.Var5GmmCause != nil { updateData.Var5gMmCauseValue = *cause.Var5GmmCause } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, nil) } func (s *nsmfService) SendUpdateSmContextChangeAccessType(ue *amf_context.AmfUe, smContext *amf_context.SmContext, anTypeCanBeChanged bool) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.AnTypeCanBeChanged = anTypeCanBeChanged - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, nil) } func (s *nsmfService) SendUpdateSmContextN2Info( ue *amf_context.AmfUe, smContext *amf_context.SmContext, n2SmType models.N2SmInfoType, n2SmInfo []byte) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.N2SmInfoType = n2SmType updateData.N2SmInfo = new(models.RefToBinaryData) updateData.N2SmInfo.ContentId = n2sminfocon updateData.UeLocation = &ue.Location - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, n2SmInfo) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, n2SmInfo) } func (s *nsmfService) SendUpdateSmContextXnHandover( ue *amf_context.AmfUe, smContext *amf_context.SmContext, n2SmType models.N2SmInfoType, n2SmInfo []byte) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} if n2SmType != "" { updateData.N2SmInfoType = n2SmType updateData.N2SmInfo = new(models.RefToBinaryData) @@ -328,21 +325,21 @@ func (s *nsmfService) SendUpdateSmContextXnHandover( updateData.PresenceInLadn = models.PresenceState_OUT_OF_AREA } } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, n2SmInfo) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, n2SmInfo) } func (s *nsmfService) SendUpdateSmContextXnHandoverFailed( ue *amf_context.AmfUe, smContext *amf_context.SmContext, n2SmType models.N2SmInfoType, n2SmInfo []byte) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} if n2SmType != "" { updateData.N2SmInfoType = n2SmType updateData.N2SmInfo = new(models.RefToBinaryData) updateData.N2SmInfo.ContentId = n2sminfocon } updateData.FailedToBeSwitched = true - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, n2SmInfo) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, n2SmInfo) } func (s *nsmfService) SendUpdateSmContextN2HandoverPreparing( @@ -350,9 +347,9 @@ func (s *nsmfService) SendUpdateSmContextN2HandoverPreparing( smContext *amf_context.SmContext, n2SmType models.N2SmInfoType, n2SmInfo []byte, amfid string, targetId *models.NgRanTargetId) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} if n2SmType != "" { updateData.N2SmInfoType = n2SmType updateData.N2SmInfo = new(models.RefToBinaryData) @@ -364,28 +361,28 @@ func (s *nsmfService) SendUpdateSmContextN2HandoverPreparing( if amfid != "" { updateData.TargetServingNfId = amfid } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, n2SmInfo) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, n2SmInfo) } func (s *nsmfService) SendUpdateSmContextN2HandoverPrepared( ue *amf_context.AmfUe, smContext *amf_context.SmContext, n2SmType models.N2SmInfoType, n2SmInfo []byte) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} if n2SmType != "" { updateData.N2SmInfoType = n2SmType updateData.N2SmInfo = new(models.RefToBinaryData) updateData.N2SmInfo.ContentId = n2sminfocon } updateData.HoState = models.HoState_PREPARED - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, n2SmInfo) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, n2SmInfo) } func (s *nsmfService) SendUpdateSmContextN2HandoverComplete( ue *amf_context.AmfUe, smContext *amf_context.SmContext, amfid string, guami *models.Guami) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.HoState = models.HoState_COMPLETED if amfid != "" { updateData.ServingNfId = amfid @@ -399,14 +396,14 @@ func (s *nsmfService) SendUpdateSmContextN2HandoverComplete( updateData.PresenceInLadn = models.PresenceState_OUT_OF_AREA } } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, nil) } func (s *nsmfService) SendUpdateSmContextN2HandoverCanceled(ue *amf_context.AmfUe, smContext *amf_context.SmContext, cause amf_context.CauseAll) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} // nolint openapi/model misspelling updateData.HoState = models.HoState_CANCELLED if cause.Cause != nil { @@ -418,27 +415,27 @@ func (s *nsmfService) SendUpdateSmContextN2HandoverCanceled(ue *amf_context.AmfU if cause.Var5GmmCause != nil { updateData.Var5gMmCauseValue = *cause.Var5GmmCause } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, nil) } func (s *nsmfService) SendUpdateSmContextHandoverBetweenAccessType( ue *amf_context.AmfUe, smContext *amf_context.SmContext, targetAccessType models.AccessType, n1SmMsg []byte) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.AnType = targetAccessType if n1SmMsg != nil { updateData.N1SmMsg = new(models.RefToBinaryData) updateData.N1SmMsg.ContentId = "N1Msg" } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, n1SmMsg, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, n1SmMsg, nil) } func (s *nsmfService) SendUpdateSmContextHandoverBetweenAMF( ue *amf_context.AmfUe, smContext *amf_context.SmContext, amfid string, guami *models.Guami, activate bool) ( - *models.UpdateSmContextResponse, *models.UpdateSmContextErrorResponse, *models.ProblemDetails, error, + *models.UpdateSmContextResponse200, *models.UpdateSmContextResponse400, *models.ProblemDetails, error, ) { - updateData := models.SmContextUpdateData{} + updateData := models.SmfPduSessionSmContextUpdateData{} updateData.ServingNfId = amfid updateData.ServingNetwork = guami.PlmnId updateData.Guami = guami @@ -453,12 +450,12 @@ func (s *nsmfService) SendUpdateSmContextHandoverBetweenAMF( } } } - return s.consumer.SendUpdateSmContextRequest(smContext, updateData, nil, nil) + return s.consumer.SendUpdateSmContextRequest(smContext, &updateData, nil, nil) } func (s *nsmfService) SendUpdateSmContextRequest(smContext *amf_context.SmContext, - updateData models.SmContextUpdateData, n1Msg []byte, n2Info []byte) ( - response *models.UpdateSmContextResponse, errorResponse *models.UpdateSmContextErrorResponse, + updateData *models.SmfPduSessionSmContextUpdateData, n1Msg []byte, n2Info []byte) ( + response *models.UpdateSmContextResponse200, errorResponse *models.UpdateSmContextResponse400, problemDetail *models.ProblemDetails, err1 error, ) { client := s.getPDUSessionClient(smContext.SmfUri()) @@ -466,43 +463,43 @@ func (s *nsmfService) SendUpdateSmContextRequest(smContext *amf_context.SmContex return nil, nil, nil, openapi.ReportError("smf not found") } - var updateSmContextRequest models.UpdateSmContextRequest - updateSmContextRequest.JsonData = &updateData - updateSmContextRequest.BinaryDataN1SmMessage = n1Msg - updateSmContextRequest.BinaryDataN2SmInformation = n2Info + smCtxRef := smContext.SmContextRef() + updateSmContextRequest := Nsmf_PDUSession.UpdateSmContextRequest{ + SmContextRef: &smCtxRef, + UpdateSmContextRequest: &models.UpdateSmContextRequest{ + JsonData: updateData, + BinaryDataN1SmMessage: n1Msg, + BinaryDataN2SmInformation: n2Info, + }, + } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NSMF_PDUSESSION, models.NfType_SMF) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NSMF_PDUSESSION, models.NrfNfManagementNfType_SMF) if err != nil { return nil, nil, nil, err } - updateSmContextReponse, httpResponse, err := client.IndividualSMContextApi. - UpdateSmContext(ctx, smContext.SmContextRef(), - updateSmContextRequest) - defer func() { - if httpResponse != nil { - if rspCloseErr := httpResponse.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("UpdateSmContext response body cannot close: %+v", - rspCloseErr) + updateSmContextReponse, localErr := client.IndividualSMContextApi. + UpdateSmContext(ctx, &updateSmContextRequest) + if localErr == nil { + response = &updateSmContextReponse.UpdateSmContextResponse200 + } else { + err1 = localErr + switch errType := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nsmf_PDUSession.UpdateSmContextError: + problemDetail = &errModel.ProblemDetails + errorResponse = &errModel.UpdateSmContextResponse400 + case error: + err1 = errModel + default: + err1 = openapi.ReportError("openapi error") } + case error: + problemDetail = openapi.ProblemDetailsSystemFailure(err1.Error()) + default: + err1 = openapi.ReportError("server no response") } - }() - if err == nil { - response = &updateSmContextReponse - } else if httpResponse != nil { - if httpResponse.Status != err.Error() { - err1 = err - return response, errorResponse, problemDetail, err1 - } - switch httpResponse.StatusCode { - case 400, 403, 404, 500, 503: - errResponse := err.(openapi.GenericOpenAPIError).Model().(models.UpdateSmContextErrorResponse) - errorResponse = &errResponse - case 411, 413, 415, 429: - problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetail = &problem - } - } else { - err1 = openapi.ReportError("server no response") } return response, errorResponse, problemDetail, err1 } @@ -519,42 +516,49 @@ func (s *nsmfService) SendReleaseSmContextRequest(ue *amf_context.AmfUe, smConte } releaseData := s.buildReleaseSmContextRequest(ue, cause, n2SmInfoType, n2Info) - releaseSmContextRequest := models.ReleaseSmContextRequest{ - JsonData: &releaseData, + + smCtxRef := smContext.SmContextRef() + releaseSmContextRequest := Nsmf_PDUSession.ReleaseSmContextRequest{ + SmContextRef: &smCtxRef, + ReleaseSmContextRequest: &models.ReleaseSmContextRequest{ + JsonData: &releaseData, + }, } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NSMF_PDUSESSION, models.NfType_SMF) + + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NSMF_PDUSESSION, models.NrfNfManagementNfType_SMF) if err != nil { return nil, err } - response, err1 := client.IndividualSMContextApi.ReleaseSmContext( - ctx, smContext.SmContextRef(), releaseSmContextRequest) - defer func() { - if response != nil { - if rspCloseErr := response.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("ReleaseSmContext response body cannot close: %+v", - rspCloseErr) - } - } - }() - if err1 == nil { + _, localErr := client.IndividualSMContextApi.ReleaseSmContext( + ctx, &releaseSmContextRequest) + + if localErr == nil { ue.SmContextList.Delete(smContext.PduSessionID()) - } else if response != nil && response.Status == err1.Error() { - if response.StatusCode == 404 { - // assume succeeded to release SmContext - ue.SmContextList.Delete(smContext.PduSessionID()) - } else { - problem := err1.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - detail = &problem - } } else { - err = err1 + err = localErr + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Nsmf_PDUSession.ReleaseSmContextError: + detail = &errorModel.ProblemDetails + case error: + detail = openapi.ProblemDetailsSystemFailure(errorModel.Error()) + default: + err = openapi.ReportError("openapi error") + } + case error: + detail = openapi.ProblemDetailsSystemFailure(apiErr.Error()) + default: + err = openapi.ReportError("openapi error") + } } return detail, err } func (s *nsmfService) buildReleaseSmContextRequest( ue *amf_context.AmfUe, cause *amf_context.CauseAll, n2SmInfoType models.N2SmInfoType, n2Info []byte) ( - releaseData models.SmContextReleaseData, + releaseData models.SmfPduSessionSmContextReleaseData, ) { if cause != nil { if cause.Cause != nil { diff --git a/internal/sbi/consumer/udm_service.go b/internal/sbi/consumer/udm_service.go index 331cc1a..9774a0a 100644 --- a/internal/sbi/consumer/udm_service.go +++ b/internal/sbi/consumer/udm_service.go @@ -4,15 +4,12 @@ import ( "fmt" "sync" - "github.com/antihax/optional" - amf_context "github.com/free5gc/amf/internal/context" - "github.com/free5gc/amf/internal/logger" "github.com/free5gc/amf/pkg/factory" "github.com/free5gc/openapi" - "github.com/free5gc/openapi/Nudm_SubscriberDataManagement" - "github.com/free5gc/openapi/Nudm_UEContextManagement" "github.com/free5gc/openapi/models" + Nudm_SubscriberDataManagement "github.com/free5gc/openapi/udm/SubscriberDataManagement" + Nudm_UEContextManagement "github.com/free5gc/openapi/udm/UEContextManagement" ) type nudmService struct { @@ -75,7 +72,7 @@ func (s *nudmService) PutUpuAck(ue *amf_context.AmfUe, upuMacIue string) error { return openapi.ReportError("udm not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return err } @@ -83,19 +80,13 @@ func (s *nudmService) PutUpuAck(ue *amf_context.AmfUe, upuMacIue string) error { ackInfo := models.AcknowledgeInfo{ UpuMacIue: upuMacIue, } - upuOpt := Nudm_SubscriberDataManagement.PutUpuAckParamOpts{ - AcknowledgeInfo: optional.NewInterface(ackInfo), + upuReq := Nudm_SubscriberDataManagement.UpuAckRequest{ + Supi: &ue.Supi, + AcknowledgeInfo: &ackInfo, } - httpResp, err := client.ProvidingAcknowledgementOfUEParametersUpdateApi. - PutUpuAck(ctx, ue.Supi, &upuOpt) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("PutUpuAck response body cannot close: %+v", - rspCloseErr) - } - } - }() + _, err = client.ProvidingAcknowledgementOfUEParametersUpdateApi. + UpuAck(ctx, &upuReq) + return err } @@ -105,37 +96,44 @@ func (s *nudmService) SDMGetAmData(ue *amf_context.AmfUe) (problemDetails *model return nil, openapi.ReportError("udm not found") } - getAmDataParamOpt := Nudm_SubscriberDataManagement.GetAmDataParamOpts{ - PlmnId: optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId)), + getAmDataParamReq := Nudm_SubscriberDataManagement.GetAmDataRequest{ + Supi: &ue.Supi, + PlmnId: &models.PlmnIdNid{ + Mnc: ue.PlmnId.Mnc, + Mcc: ue.PlmnId.Mcc, + }, } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } - data, httpResp, localErr := client.AccessAndMobilitySubscriptionDataRetrievalApi.GetAmData( - ctx, ue.Supi, &getAmDataParamOpt) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("GetAmData response body cannot close: %+v", - rspCloseErr) - } - } - }() + data, localErr := client.AccessAndMobilitySubscriptionDataRetrievalApi.GetAmData( + ctx, &getAmDataParamReq) if localErr == nil { - ue.AccessAndMobilitySubscriptionData = &data - ue.Gpsi = data.Gpsis[0] // TODO: select GPSI - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err + ue.AccessAndMobilitySubscriptionData = &data.AccessAndMobilitySubscriptionData + if len(data.AccessAndMobilitySubscriptionData.Gpsis) > 0 { + ue.Gpsi = data.AccessAndMobilitySubscriptionData.Gpsis[0] // TODO: select GPSI } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("server no response") + err = localErr + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Nudm_SubscriberDataManagement.GetAmDataError: + problemDetails = &errorModel.ProblemDetails + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(errorModel.Error()) + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(apiErr.Error()) + default: + err = openapi.ReportError("openapi error") + } } return problemDetails, err } @@ -146,36 +144,39 @@ func (s *nudmService) SDMGetSmfSelectData(ue *amf_context.AmfUe) (problemDetails return nil, openapi.ReportError("udm not found") } - paramOpt := Nudm_SubscriberDataManagement.GetSmfSelectDataParamOpts{ - PlmnId: optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId)), + paramReq := Nudm_SubscriberDataManagement.GetSmfSelDataRequest{ + Supi: &ue.Supi, + PlmnId: &ue.PlmnId, } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } - data, httpResp, localErr := client.SMFSelectionSubscriptionDataRetrievalApi. - GetSmfSelectData(ctx, ue.Supi, ¶mOpt) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("GetSmfSelectData response body cannot close: %+v", - rspCloseErr) - } - } - }() + data, localErr := client.SMFSelectionSubscriptionDataRetrievalApi. + GetSmfSelData(ctx, ¶mReq) + if localErr == nil { - ue.SmfSelectionData = &data - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem + ue.SmfSelectionData = &data.SmfSelectionSubscriptionData } else { - err = openapi.ReportError("server no response") + err = localErr + switch errType := localErr.(type) { + case openapi.GenericOpenAPIError: + // API error + switch errModel := errType.Model().(type) { + case Nudm_SubscriberDataManagement.GetSmfSelDataError: + problemDetails = &errModel.ProblemDetails + case error: + err = errModel + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(err.Error()) + default: + err = openapi.ReportError("openapi error") + } } return problemDetails, err @@ -189,32 +190,36 @@ func (s *nudmService) SDMGetUeContextInSmfData( return nil, openapi.ReportError("udm not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } - data, httpResp, localErr := client.UEContextInSMFDataRetrievalApi. - GetUeContextInSmfData(ctx, ue.Supi, nil) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("GetUeContextInSmfData response body cannot close: %+v", - rspCloseErr) - } - } - }() + getUeCtxInSmfDataReq := Nudm_SubscriberDataManagement.GetUeCtxInSmfDataRequest{ + Supi: &ue.Supi, + } + + data, localErr := client.UEContextInSMFDataRetrievalApi. + GetUeCtxInSmfData(ctx, &getUeCtxInSmfDataReq) if localErr == nil { - ue.UeContextInSmfData = &data - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return nil, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem + ue.UeContextInSmfData = &data.UeContextInSmfData } else { - err = openapi.ReportError("server no response") + err = localErr + switch errType := localErr.(type) { + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nudm_SubscriberDataManagement.GetUeCtxInSmfDataError: + problemDetails = &errModel.ProblemDetails + case error: + err = errModel + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(err.Error()) + default: + return nil, openapi.ReportError("openapi error") + } } return problemDetails, err @@ -232,33 +237,38 @@ func (s *nudmService) SDMSubscribe(ue *amf_context.AmfUe) (problemDetails *model PlmnId: &ue.PlmnId, } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + subscribeReq := Nudm_SubscriberDataManagement.SubscribeRequest{ + UeId: &ue.Supi, + SdmSubscription: &sdmSubscription, + } + + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } - resSubscription, httpResp, localErr := client.SubscriptionCreationApi.Subscribe( - ctx, ue.Supi, sdmSubscription) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("Subscribe response body cannot close: %+v", - rspCloseErr) - } - } - }() + resSubscription, localErr := client.SubscriptionCreationApi.Subscribe( + ctx, &subscribeReq) if localErr == nil { - ue.SdmSubscriptionId = resSubscription.SubscriptionId + ue.SdmSubscriptionId = resSubscription.SdmSubscription.SubscriptionId return problemDetails, err - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("server no response") + err = localErr + switch errType := localErr.(type) { + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nudm_SubscriberDataManagement.SubscribeError: + problemDetails = &errModel.ProblemDetails + case error: + err = errModel + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(err.Error()) + default: + return nil, openapi.ReportError("openapi error") + } } return problemDetails, err } @@ -271,27 +281,21 @@ func (s *nudmService) SDMGetSliceSelectionSubscriptionData( return nil, openapi.ReportError("udm not found") } - paramOpt := Nudm_SubscriberDataManagement.GetNssaiParamOpts{ - PlmnId: optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId)), + paramReq := Nudm_SubscriberDataManagement.GetNSSAIRequest{ + Supi: &ue.Supi, + PlmnId: &ue.PlmnId, } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } - nssai, httpResp, localErr := client.SliceSelectionSubscriptionDataRetrievalApi. - GetNssai(ctx, ue.Supi, ¶mOpt) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("GetNssai response body cannot close: %+v", - rspCloseErr) - } - } - }() + nssai, localErr := client.SliceSelectionSubscriptionDataRetrievalApi. + GetNSSAI(ctx, ¶mReq) + if localErr == nil { - for _, defaultSnssai := range nssai.DefaultSingleNssais { + for _, defaultSnssai := range nssai.Nssai.DefaultSingleNssais { subscribedSnssai := models.SubscribedSnssai{ SubscribedSnssai: &models.Snssai{ Sst: defaultSnssai.Sst, @@ -301,7 +305,7 @@ func (s *nudmService) SDMGetSliceSelectionSubscriptionData( } ue.SubscribedNssai = append(ue.SubscribedNssai, subscribedSnssai) } - for _, snssai := range nssai.SingleNssais { + for _, snssai := range nssai.Nssai.SingleNssais { subscribedSnssai := models.SubscribedSnssai{ SubscribedSnssai: &models.Snssai{ Sst: snssai.Sst, @@ -311,15 +315,24 @@ func (s *nudmService) SDMGetSliceSelectionSubscriptionData( } ue.SubscribedNssai = append(ue.SubscribedNssai, subscribedSnssai) } - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return problemDetails, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem } else { - err = openapi.ReportError("server no response") + err = localErr + // API error + switch errType := localErr.(type) { + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nudm_SubscriberDataManagement.GetNSSAIError: + problemDetails = &errModel.ProblemDetails + case error: + err = errModel + default: + err = openapi.ReportError("openapi error") + } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(err.Error()) + default: + return nil, openapi.ReportError("openapi error") + } } return problemDetails, err } @@ -330,31 +343,36 @@ func (s *nudmService) SDMUnsubscribe(ue *amf_context.AmfUe) (problemDetails *mod return nil, openapi.ReportError("udm not found") } - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_SDM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } - httpResp, localErr := client.SubscriptionDeletionApi.Unsubscribe(ctx, ue.Supi, ue.SdmSubscriptionId) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("Unsubscribe response body cannot close: %+v", - rspCloseErr) + unsubscribeReq := Nudm_SubscriberDataManagement.UnsubscribeRequest{ + UeId: &ue.Supi, + SubscriptionId: &ue.SdmSubscriptionId, + } + + _, localErr := client.SubscriptionDeletionApi.Unsubscribe(ctx, &unsubscribeReq) + + if localErr != nil { + err = localErr + switch errType := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errModel := errType.Model().(type) { + case Nudm_SubscriberDataManagement.UnsubscribeError: + problemDetails = &errModel.ProblemDetails + case error: + err = errModel + default: + err = openapi.ReportError("openapi error") } + case error: + problemDetails = openapi.ProblemDetailsSystemFailure(err.Error()) + default: + return nil, openapi.ReportError("openapi error") } - }() - if localErr == nil { - return problemDetails, err - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - err = localErr - return nil, err - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - problemDetails = &problem - } else { - err = openapi.ReportError("server no response") } return problemDetails, err } @@ -368,7 +386,7 @@ func (s *nudmService) UeCmRegistration( } amfSelf := amf_context.GetSelf() - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UEAU, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UEAU, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } @@ -391,27 +409,33 @@ func (s *nudmService) UeCmRegistration( ImsVoPs: models.ImsVoPs_HOMOGENEOUS_NON_SUPPORT, } - _, httpResp, localErr := client.AMFRegistrationFor3GPPAccessApi.Registration(ctx, - ue.Supi, registrationData) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("Registration response body cannot close: %+v", - rspCloseErr) - } - } - }() + regReq := Nudm_UEContextManagement.Call3GppRegistrationRequest{ + UeId: &ue.Supi, + Amf3GppAccessRegistration: ®istrationData, + } + + _, localErr := client.AMFRegistrationFor3GPPAccessApi.Call3GppRegistration(ctx, + ®Req) if localErr == nil { ue.UeCmRegistered[accessType] = true return nil, nil - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - return nil, localErr - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return &problem, nil } else { - return nil, openapi.ReportError("server no response") + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Nudm_UEContextManagement.Call3GppRegistrationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } } case models.AccessType_NON_3_GPP_ACCESS: registrationData := models.AmfNon3GppAccessRegistration{ @@ -420,27 +444,33 @@ func (s *nudmService) UeCmRegistration( RatType: ue.RatType, } - _, httpResp, localErr := client.AMFRegistrationForNon3GPPAccessApi. - Register(ctx, ue.Supi, registrationData) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("Register response body cannot close: %+v", - rspCloseErr) - } - } - }() + regReq := Nudm_UEContextManagement.Non3GppRegistrationRequest{ + UeId: &ue.Supi, + AmfNon3GppAccessRegistration: ®istrationData, + } + + _, localErr := client.AMFRegistrationForNon3GPPAccessApi. + Non3GppRegistration(ctx, ®Req) + if localErr == nil { ue.UeCmRegistered[accessType] = true return nil, nil - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - return nil, localErr - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return &problem, nil } else { - return nil, openapi.ReportError("server no response") + switch apiErr := localErr.(type) { + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Nudm_UEContextManagement.Non3GppRegistrationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } } } @@ -456,7 +486,7 @@ func (s *nudmService) UeCmDeregistration( } amfSelf := amf_context.GetSelf() - ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NfType_UDM) + ctx, _, err := amf_context.GetSelf().GetTokenCtx(models.ServiceName_NUDM_UECM, models.NrfNfManagementNfType_UDM) if err != nil { return nil, err } @@ -468,53 +498,66 @@ func (s *nudmService) UeCmDeregistration( PurgeFlag: true, } - httpResp, localErr := client.ParameterUpdateInTheAMFRegistrationFor3GPPAccessApi.Update(ctx, - ue.Supi, modificationData) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("Update response body cannot close: %+v", - rspCloseErr) - } - } - }() + modificationReq := Nudm_UEContextManagement.Update3GppRegistrationRequest{ + UeId: &ue.Supi, + Amf3GppAccessRegistrationModification: &modificationData, + } + + _, localErr := client.ParameterUpdateInTheAMFRegistrationFor3GPPAccessApi.Update3GppRegistration(ctx, + &modificationReq) + if localErr == nil { return nil, nil - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - return nil, localErr - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return &problem, nil } else { - return nil, openapi.ReportError("server no response") + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Nudm_UEContextManagement.Update3GppRegistrationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } } case models.AccessType_NON_3_GPP_ACCESS: modificationData := models.AmfNon3GppAccessRegistrationModification{ Guami: &amfSelf.ServedGuamiList[0], PurgeFlag: true, } + modificationReq := Nudm_UEContextManagement.UpdateNon3GppRegistrationRequest{ + UeId: &ue.Supi, + AmfNon3GppAccessRegistrationModification: &modificationData, + } + + _, localErr := client.ParameterUpdateInTheAMFRegistrationForNon3GPPAccessApi.UpdateNon3GppRegistration( + ctx, &modificationReq) - httpResp, localErr := client.ParameterUpdateInTheAMFRegistrationForNon3GPPAccessApi.UpdateAmfNon3gppAccess( - ctx, ue.Supi, modificationData) - defer func() { - if httpResp != nil { - if rspCloseErr := httpResp.Body.Close(); rspCloseErr != nil { - logger.ConsumerLog.Errorf("UpdateAmfNon3gppAccess response body cannot close: %+v", - rspCloseErr) - } - } - }() if localErr == nil { return nil, nil - } else if httpResp != nil { - if httpResp.Status != localErr.Error() { - return nil, localErr - } - problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) - return &problem, nil } else { - return nil, openapi.ReportError("server no response") + switch apiErr := localErr.(type) { + // API error + case openapi.GenericOpenAPIError: + switch errorModel := apiErr.Model().(type) { + case Nudm_UEContextManagement.UpdateNon3GppRegistrationError: + return &errorModel.ProblemDetails, nil + case error: + return openapi.ProblemDetailsSystemFailure(errorModel.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } + case error: + return openapi.ProblemDetailsSystemFailure(apiErr.Error()), nil + default: + return nil, openapi.ReportError("openapi error") + } } } diff --git a/internal/sbi/processor/callback.go b/internal/sbi/processor/callback.go index 84ce74f..8418038 100644 --- a/internal/sbi/processor/callback.go +++ b/internal/sbi/processor/callback.go @@ -19,7 +19,7 @@ import ( ) func (p *Processor) HandleSmContextStatusNotify(c *gin.Context, - smContextStatusNotification models.SmContextStatusNotification, + smContextStatusNotification models.SmfPduSessionSmContextStatusNotification, ) { logger.ProducerLog.Infoln("[AMF] Handle SmContext Status Notify") @@ -41,7 +41,7 @@ func (p *Processor) HandleSmContextStatusNotify(c *gin.Context, } func (p *Processor) SmContextStatusNotifyProcedure(supi string, pduSessionID int32, - smContextStatusNotification models.SmContextStatusNotification, + smContextStatusNotification models.SmfPduSessionSmContextStatusNotification, ) *models.ProblemDetails { amfSelf := context.GetSelf() @@ -91,7 +91,9 @@ func (p *Processor) SmContextStatusNotifyProcedure(supi string, pduSessionID int return nil } -func (p *Processor) HandleAmPolicyControlUpdateNotifyUpdate(c *gin.Context, policyUpdate models.PolicyUpdate) { +func (p *Processor) HandleAmPolicyControlUpdateNotifyUpdate(c *gin.Context, + policyUpdate models.PcfAmPolicyControlPolicyUpdate, +) { logger.ProducerLog.Infoln("Handle AM Policy Control Update Notify [Policy update notification]") polAssoID := c.Param("polAssoId") @@ -105,7 +107,7 @@ func (p *Processor) HandleAmPolicyControlUpdateNotifyUpdate(c *gin.Context, poli } func (p *Processor) AmPolicyControlUpdateNotifyUpdateProcedure(polAssoID string, - policyUpdate models.PolicyUpdate, + policyUpdate models.PcfAmPolicyControlPolicyUpdate, ) *models.ProblemDetails { amfSelf := context.GetSelf() @@ -126,7 +128,7 @@ func (p *Processor) AmPolicyControlUpdateNotifyUpdateProcedure(polAssoID string, ue.RequestTriggerLocationChange = false for _, trigger := range policyUpdate.Triggers { - if trigger == models.RequestTrigger_LOC_CH { + if trigger == models.PcfAmPolicyControlRequestTrigger_LOC_CH { ue.RequestTriggerLocationChange = true } // if trigger == models.RequestTrigger_PRA_CH { @@ -190,7 +192,7 @@ func (p *Processor) AmPolicyControlUpdateNotifyUpdateProcedure(polAssoID string, // TS 29.507 4.2.4.3 func (p *Processor) HandleAmPolicyControlUpdateNotifyTerminate(c *gin.Context, - terminationNotification models.TerminationNotification, + terminationNotification models.PcfAmPolicyControlTerminationNotification, ) { logger.ProducerLog.Infoln("Handle AM Policy Control Update Notify [Request for termination of the policy association]") @@ -205,7 +207,7 @@ func (p *Processor) HandleAmPolicyControlUpdateNotifyTerminate(c *gin.Context, } func (p *Processor) AmPolicyControlUpdateNotifyTerminateProcedure(polAssoID string, - terminationNotification models.TerminationNotification, + terminationNotification models.PcfAmPolicyControlTerminationNotification, ) *models.ProblemDetails { amfSelf := context.GetSelf() @@ -244,7 +246,7 @@ func (p *Processor) AmPolicyControlUpdateNotifyTerminateProcedure(polAssoID stri } // TS 23.502 4.2.2.2.3 Registration with AMF re-allocation -func (p *Processor) HandleN1MessageNotify(c *gin.Context, n1MessageNotify models.N1MessageNotify) { +func (p *Processor) HandleN1MessageNotify(c *gin.Context, n1MessageNotify models.N1MessageNotifyRequest) { logger.ProducerLog.Infoln("[AMF] Handle N1 Message Notify") problemDetails := p.N1MessageNotifyProcedure(n1MessageNotify) @@ -255,13 +257,13 @@ func (p *Processor) HandleN1MessageNotify(c *gin.Context, n1MessageNotify models } } -func (p *Processor) N1MessageNotifyProcedure(n1MessageNotify models.N1MessageNotify) *models.ProblemDetails { +func (p *Processor) N1MessageNotifyProcedure(n1MessageNotify models.N1MessageNotifyRequest) *models.ProblemDetails { logger.ProducerLog.Debugf("n1MessageNotify: %+v", n1MessageNotify) amfSelf := context.GetSelf() registrationCtxtContainer := n1MessageNotify.JsonData.RegistrationCtxtContainer - if registrationCtxtContainer.UeContext == nil { + if registrationCtxtContainer == nil || registrationCtxtContainer.UeContext == nil { problemDetails := &models.ProblemDetails{ Status: http.StatusBadRequest, Cause: "MANDATORY_IE_MISSING", // Defined in TS 29.500 5.2.7.2 @@ -272,6 +274,8 @@ func (p *Processor) N1MessageNotifyProcedure(n1MessageNotify models.N1MessageNot ran, ok := amfSelf.AmfRanFindByRanID(*registrationCtxtContainer.RanNodeId) if !ok { + logger.CallbackLog.Warnln("AmfRanFindByRanID not found: ", *registrationCtxtContainer.RanNodeId) + problemDetails := &models.ProblemDetails{ Status: http.StatusBadRequest, Cause: "MANDATORY_IE_INCORRECT", @@ -299,7 +303,7 @@ func (p *Processor) N1MessageNotifyProcedure(n1MessageNotify models.N1MessageNot amfUe.Lock.Lock() defer amfUe.Lock.Unlock() - amfUe.CopyDataFromUeContextModel(*ueContext) + amfUe.CopyDataFromUeContextModel(ueContext) ranUe := ran.RanUeFindByRanUeNgapID(int64(registrationCtxtContainer.AnN2ApId)) diff --git a/internal/sbi/processor/event_exposure.go b/internal/sbi/processor/event_exposure.go index 3f830a8..bb3cea2 100644 --- a/internal/sbi/processor/event_exposure.go +++ b/internal/sbi/processor/event_exposure.go @@ -62,7 +62,26 @@ func (p *Processor) CreateAMFEventSubscriptionProcedure(createEventSubscription // store subscription in context ueEventSubscription := context.AmfUeEventSubscription{} - ueEventSubscription.EventSubscription = &contextEventSubscription.EventSubscription + extCtxEventSub := models.ExtAmfEventSubscription{ + EventList: contextEventSubscription.EventSubscription.EventList, + EventNotifyUri: contextEventSubscription.EventSubscription.EventNotifyUri, + NotifyCorrelationId: contextEventSubscription.EventSubscription.NotifyCorrelationId, + NfId: contextEventSubscription.EventSubscription.NfId, + SubsChangeNotifyUri: contextEventSubscription.EventSubscription.SubsChangeNotifyUri, + SubsChangeNotifyCorrelationId: contextEventSubscription.EventSubscription.SubsChangeNotifyCorrelationId, + Supi: contextEventSubscription.EventSubscription.Supi, + GroupId: contextEventSubscription.EventSubscription.GroupId, + ExcludeSupiList: contextEventSubscription.EventSubscription.ExcludeSupiList, + ExcludeGpsiList: contextEventSubscription.EventSubscription.ExcludeGpsiList, + IncludeSupiList: contextEventSubscription.EventSubscription.IncludeSupiList, + IncludeGpsiList: contextEventSubscription.EventSubscription.IncludeGpsiList, + Gpsi: contextEventSubscription.EventSubscription.Gpsi, + Pei: contextEventSubscription.EventSubscription.Pei, + AnyUE: contextEventSubscription.EventSubscription.AnyUE, + Options: contextEventSubscription.EventSubscription.Options, + SourceNfType: contextEventSubscription.EventSubscription.SourceNfType, + } + ueEventSubscription.EventSubscription = &extCtxEventSub ueEventSubscription.Timestamp = time.Now().UTC() if subscription.Options != nil && subscription.Options.Trigger == models.AmfEventTrigger_CONTINUOUS { @@ -78,7 +97,7 @@ func (p *Processor) CreateAMFEventSubscriptionProcedure(createEventSubscription return nil, problemDetails } - for _, events := range *subscription.EventList { + for _, events := range subscription.EventList { immediateFlags = append(immediateFlags, events.ImmediateFlag) if events.ImmediateFlag { isImmediate = true @@ -150,7 +169,7 @@ func (p *Processor) CreateAMFEventSubscriptionProcedure(createEventSubscription } for i, flag := range immediateFlags { if flag { - report, ok := p.newAmfEventReport(ue, (*subscription.EventList)[i].Type, newSubscriptionID) + report, ok := p.newAmfEventReport(ue, subscription.EventList[i].Type, newSubscriptionID) if ok { reportlist = append(reportlist, report) } @@ -174,7 +193,7 @@ func (p *Processor) CreateAMFEventSubscriptionProcedure(createEventSubscription if ue.GroupID == subscription.GroupId { for i, flag := range immediateFlags { if flag { - report, ok := p.newAmfEventReport(ue, (*subscription.EventList)[i].Type, newSubscriptionID) + report, ok := p.newAmfEventReport(ue, subscription.EventList[i].Type, newSubscriptionID) if ok { reportlist = append(reportlist, report) } @@ -197,7 +216,7 @@ func (p *Processor) CreateAMFEventSubscriptionProcedure(createEventSubscription } for i, flag := range immediateFlags { if flag { - report, ok := p.newAmfEventReport(ue, (*subscription.EventList)[i].Type, newSubscriptionID) + report, ok := p.newAmfEventReport(ue, subscription.EventList[i].Type, newSubscriptionID) if ok { reportlist = append(reportlist, report) } @@ -293,9 +312,9 @@ func (p *Processor) ModifyAMFEventSubscriptionProcedure( return nil, problemDetails } - if modifySubscriptionRequest.OptionItem != nil { - contextSubscription.Expiry = modifySubscriptionRequest.OptionItem.Value - } else if modifySubscriptionRequest.SubscriptionItemInner != nil { + if len(modifySubscriptionRequest.OptionItem) != 0 { + contextSubscription.Expiry = modifySubscriptionRequest.OptionItem[0].Value + } else if len(modifySubscriptionRequest.SubscriptionItem) != 0 { subscription := &contextSubscription.EventSubscription if !contextSubscription.IsAnyUe && !contextSubscription.IsGroupUe { if _, okAmfUeFindBySupi := amfSelf.AmfUeFindBySupi(subscription.Supi); !okAmfUeFindBySupi { @@ -306,8 +325,8 @@ func (p *Processor) ModifyAMFEventSubscriptionProcedure( return nil, problemDetails } } - op := modifySubscriptionRequest.SubscriptionItemInner.Op - index, err := strconv.Atoi(modifySubscriptionRequest.SubscriptionItemInner.Path[11:]) + op := modifySubscriptionRequest.SubscriptionItem[0].Op + index, err := strconv.Atoi(modifySubscriptionRequest.SubscriptionItem[0].Path[11:]) if err != nil { problemDetails := &models.ProblemDetails{ Status: http.StatusInternalServerError, @@ -315,27 +334,27 @@ func (p *Processor) ModifyAMFEventSubscriptionProcedure( } return nil, problemDetails } - lists := (*subscription.EventList) - eventlistLen := len(*subscription.EventList) + lists := (subscription.EventList) + eventlistLen := len(subscription.EventList) switch op { case "replace": - event := *modifySubscriptionRequest.SubscriptionItemInner.Value + event := *modifySubscriptionRequest.SubscriptionItem[0].Value if index < eventlistLen { - (*subscription.EventList)[index] = event + (subscription.EventList)[index] = event } case "remove": if index < eventlistLen { eventlist := []models.AmfEvent{} eventlist = append(eventlist, lists[:index]...) eventlist = append(eventlist, lists[index+1:]...) - *subscription.EventList = eventlist + subscription.EventList = eventlist } case "add": - event := *modifySubscriptionRequest.SubscriptionItemInner.Value + event := *modifySubscriptionRequest.SubscriptionItem[0].Value eventlist := []models.AmfEvent{} eventlist = append(eventlist, lists...) eventlist = append(eventlist, event) - *subscription.EventList = eventlist + subscription.EventList = eventlist } } @@ -411,8 +430,6 @@ func (p *Processor) newAmfEventReport(ue *context.AmfUe, amfEventType models.Amf report.CmInfoList = ue.GetCmInfo() case models.AmfEventType_REACHABILITY_REPORT: report.Reachability = ue.Reachability - case models.AmfEventType_SUBSCRIBED_DATA_REPORT: - report.SubscribedData = &ue.SubscribedData case models.AmfEventType_COMMUNICATION_FAILURE_REPORT: // TODO : report.CommFailure case models.AmfEventType_SUBSCRIPTION_ID_CHANGE: diff --git a/internal/sbi/processor/n1n2message.go b/internal/sbi/processor/n1n2message.go index 0c53a19..92d5ea0 100644 --- a/internal/sbi/processor/n1n2message.go +++ b/internal/sbi/processor/n1n2message.go @@ -212,7 +212,7 @@ func (p *Processor) N1N2MessageTransferProcedure(ueContextID string, reqUri stri if n2Info != nil { smInfo := requestData.N2InfoContainer.SmInfo switch smInfo.N2InfoContent.NgapIeType { - case models.NgapIeType_PDU_RES_SETUP_REQ: + case models.AmfCommunicationNgapIeType_PDU_RES_SETUP_REQ: ue.ProducerLog.Debugln("AMF Transfer NGAP PDU Session Resource Setup Request from SMF") if ue.RanUe[anType].InitialContextSetup { list := ngapType.PDUSessionResourceSetupListSUReq{} @@ -227,7 +227,7 @@ func (p *Processor) N1N2MessageTransferProcedure(ueContextID string, reqUri stri n1n2MessageTransferRspData = new(models.N1N2MessageTransferRspData) n1n2MessageTransferRspData.Cause = models.N1N2MessageTransferCause_N1_N2_TRANSFER_INITIATED return n1n2MessageTransferRspData, "", nil, nil - case models.NgapIeType_PDU_RES_MOD_REQ: + case models.AmfCommunicationNgapIeType_PDU_RES_MOD_REQ: ue.ProducerLog.Debugln("AMF Transfer NGAP PDU Session Resource Modify Request from SMF") list := ngapType.PDUSessionResourceModifyListModReq{} ngap_message.AppendPDUSessionResourceModifyListModReq(&list, smInfo.PduSessionId, nasPdu, n2Info) @@ -235,7 +235,7 @@ func (p *Processor) N1N2MessageTransferProcedure(ueContextID string, reqUri stri n1n2MessageTransferRspData = new(models.N1N2MessageTransferRspData) n1n2MessageTransferRspData.Cause = models.N1N2MessageTransferCause_N1_N2_TRANSFER_INITIATED return n1n2MessageTransferRspData, "", nil, nil - case models.NgapIeType_PDU_RES_REL_CMD: + case models.AmfCommunicationNgapIeType_PDU_RES_REL_CMD: ue.ProducerLog.Debugln("AMF Transfer NGAP PDU Session Resource Release Command from SMF") list := ngapType.PDUSessionResourceToReleaseListRelCmd{} ngap_message.AppendPDUSessionResourceToReleaseListRelCmd(&list, smInfo.PduSessionId, n2Info) @@ -257,7 +257,8 @@ func (p *Processor) N1N2MessageTransferProcedure(ueContextID string, reqUri stri // UE is CM-IDLE // 409: transfer a N2 PDU Session Resource Release Command to a 5G-AN and if the UE is in CM-IDLE - if n2Info != nil && requestData.N2InfoContainer.SmInfo.N2InfoContent.NgapIeType == models.NgapIeType_PDU_RES_REL_CMD { + if n2Info != nil && + requestData.N2InfoContainer.SmInfo.N2InfoContent.NgapIeType == models.AmfCommunicationNgapIeType_PDU_RES_REL_CMD { transferErr = new(models.N1N2MessageTransferError) transferErr.Error = &models.ProblemDetails{ Status: http.StatusConflict, diff --git a/internal/sbi/processor/notifier/n1n2message.go b/internal/sbi/processor/notifier/n1n2message.go index 5fec080..6051460 100644 --- a/internal/sbi/processor/notifier/n1n2message.go +++ b/internal/sbi/processor/notifier/n1n2message.go @@ -8,7 +8,7 @@ import ( amf_context "github.com/free5gc/amf/internal/context" "github.com/free5gc/amf/internal/logger" - "github.com/free5gc/openapi/Namf_Communication" + Namf_Communication "github.com/free5gc/openapi/amf/Communication" "github.com/free5gc/openapi/models" ) @@ -28,20 +28,18 @@ func SendN1N2TransferFailureNotification(ue *amf_context.AmfUe, cause models.N1N configuration := Namf_Communication.NewConfiguration() client := Namf_Communication.NewAPIClient(configuration) - n1N2MsgTxfrFailureNotification := models.N1N2MsgTxfrFailureNotification{ - Cause: cause, - N1n2MsgDataUri: n1n2Message.ResourceUri, + n1N2MsgTxfrFailureNotificationReq := Namf_Communication.N1N2TransferFailureNotificationRequest{ + N1N2MsgTxfrFailureNotification: &models.N1N2MsgTxfrFailureNotification{ + Cause: cause, + N1n2MsgDataUri: n1n2Message.ResourceUri, + }, } - httpResponse, err := client.N1N2MessageTransferStatusNotificationCallbackDocumentApi. - N1N2TransferFailureNotification(context.Background(), uri, n1N2MsgTxfrFailureNotification) + _, err := client.N1N2MessageCollectionCollectionApi. + N1N2TransferFailureNotification(context.Background(), uri, &n1N2MsgTxfrFailureNotificationReq) if err != nil { - if httpResponse == nil { - HttpLog.Errorln(err.Error()) - } else if err.Error() != httpResponse.Status { - HttpLog.Errorln(err.Error()) - } + HttpLog.Errorln(err.Error()) } else { ue.N1N2Message = nil } @@ -58,7 +56,7 @@ func SendN1MessageNotify(ue *amf_context.AmfUe, n1class models.N1MessageClass, n if subscription.N1NotifyCallbackUri != "" && subscription.N1MessageClass == n1class { configuration := Namf_Communication.NewConfiguration() client := Namf_Communication.NewAPIClient(configuration) - n1MessageNotify := models.N1MessageNotify{ + n1MessageNotify := models.N1MessageNotifyRequest{ JsonData: &models.N1MessageNotification{ N1NotifySubscriptionId: strconv.Itoa(int(subscriptionID)), N1MessageContainer: &models.N1MessageContainer{ @@ -71,14 +69,14 @@ func SendN1MessageNotify(ue *amf_context.AmfUe, n1class models.N1MessageClass, n }, BinaryDataN1Message: n1Msg, } - httpResponse, err := client.N1MessageNotifyCallbackDocumentApiServiceCallbackDocumentApi. - N1MessageNotify(context.Background(), subscription.N1NotifyCallbackUri, n1MessageNotify) + + n1MessageNotifyReq := Namf_Communication.N1MessageNotifyRequest{ + N1MessageNotifyRequest: &n1MessageNotify, + } + _, err := client.N1N2SubscriptionsCollectionForIndividualUEContextsCollectionApi. + N1MessageNotify(context.Background(), subscription.N1NotifyCallbackUri, &n1MessageNotifyReq) if err != nil { - if httpResponse == nil { - HttpLog.Errorln(err.Error()) - } else if err.Error() != httpResponse.Status { - HttpLog.Errorln(err.Error()) - } + HttpLog.Errorln(err.Error()) } } return true @@ -93,7 +91,7 @@ func SendN1MessageNotifyAtAMFReAllocation( configuration := Namf_Communication.NewConfiguration() client := Namf_Communication.NewAPIClient(configuration) - n1MessageNotify := models.N1MessageNotify{ + n1MessageNotify := models.N1MessageNotifyRequest{ JsonData: &models.N1MessageNotification{ N1MessageContainer: &models.N1MessageContainer{ N1MessageClass: models.N1MessageClass__5_GMM, @@ -106,23 +104,23 @@ func SendN1MessageNotifyAtAMFReAllocation( BinaryDataN1Message: n1Msg, } + n1MessageNotifyReq := Namf_Communication.N1MessageNotifyRequest{ + N1MessageNotifyRequest: &n1MessageNotify, + } + var callbackUri string for _, subscription := range ue.TargetAmfProfile.DefaultNotificationSubscriptions { - if subscription.NotificationType == models.NotificationType_N1_MESSAGES && + if subscription.NotificationType == models.NrfNfManagementNotificationType_N1_MESSAGES && subscription.N1MessageClass == models.N1MessageClass__5_GMM { callbackUri = subscription.CallbackUri break } } - httpResp, err := client.N1MessageNotifyCallbackDocumentApiServiceCallbackDocumentApi. - N1MessageNotify(context.Background(), callbackUri, n1MessageNotify) + _, err := client.N1N2SubscriptionsCollectionForIndividualUEContextsCollectionApi. + N1MessageNotify(context.Background(), callbackUri, &n1MessageNotifyReq) if err != nil { - if httpResp == nil { - HttpLog.Errorln(err.Error()) - } else if err.Error() != httpResp.Status { - HttpLog.Errorln(err.Error()) - } + HttpLog.Errorln(err.Error()) return err } return nil @@ -185,14 +183,14 @@ func SendN2InfoNotify(ue *amf_context.AmfUe, n2class models.N2InformationClass, } } - httpResponse, err := client.N2InfoNotifyCallbackDocumentApiServiceCallbackDocumentApi. - N2InfoNotify(context.Background(), subscription.N2NotifyCallbackUri, n2InformationNotify) + n2InformationNotifyReq := Namf_Communication.N2InfoNotifyRequest{ + N2InfoNotifyRequest: &n2InformationNotify, + } + + _, err := client.N1N2SubscriptionsCollectionForIndividualUEContextsCollectionApi. + N2InfoNotify(context.Background(), subscription.N2NotifyCallbackUri, &n2InformationNotifyReq) if err != nil { - if httpResponse == nil { - HttpLog.Errorln(err.Error()) - } else if err.Error() != httpResponse.Status { - HttpLog.Errorln(err.Error()) - } + HttpLog.Errorln(err.Error()) } } return true diff --git a/internal/sbi/processor/notifier/subscription.go b/internal/sbi/processor/notifier/subscription.go index 67c1a31..b23743d 100644 --- a/internal/sbi/processor/notifier/subscription.go +++ b/internal/sbi/processor/notifier/subscription.go @@ -6,7 +6,7 @@ import ( amf_context "github.com/free5gc/amf/internal/context" "github.com/free5gc/amf/internal/logger" - "github.com/free5gc/openapi/Namf_Communication" + Namf_Communication "github.com/free5gc/openapi/amf/Communication" "github.com/free5gc/openapi/models" ) @@ -14,7 +14,7 @@ func SendAmfStatusChangeNotify(amfStatus string, guamiList []models.Guami) { amfSelf := amf_context.GetSelf() amfSelf.AMFStatusSubscriptions.Range(func(key, value interface{}) bool { - subscriptionData := value.(models.SubscriptionData) + subscriptionData := value.(models.AmfCommunicationSubscriptionData) configuration := Namf_Communication.NewConfiguration() client := Namf_Communication.NewAPIClient(configuration) @@ -39,15 +39,14 @@ func SendAmfStatusChangeNotify(amfStatus string, guamiList []models.Guami) { amfStatusNotification.AmfStatusInfoList = append(amfStatusNotification.AmfStatusInfoList, amfStatusInfo) uri := subscriptionData.AmfStatusUri + amfStatusNotificationReq := Namf_Communication.AmfStatusChangeNotifyRequest{ + AmfStatusChangeNotification: &amfStatusNotification, + } logger.ProducerLog.Infof("[AMF] Send Amf Status Change Notify to %s", uri) - httpResponse, err := client.AmfStatusChangeCallbackDocumentApiServiceCallbackDocumentApi. - AmfStatusChangeNotify(context.Background(), uri, amfStatusNotification) + _, err := client.IndividualSubscriptionDocumentApi. + AmfStatusChangeNotify(context.Background(), uri, &amfStatusNotificationReq) if err != nil { - if httpResponse == nil { - HttpLog.Errorln(err.Error()) - } else if err.Error() != httpResponse.Status { - HttpLog.Errorln(err.Error()) - } + HttpLog.Errorln(err.Error()) } return true }) diff --git a/internal/sbi/processor/notifier/ue_context.go b/internal/sbi/processor/notifier/ue_context.go index 1dcf6b3..ba4923c 100644 --- a/internal/sbi/processor/notifier/ue_context.go +++ b/internal/sbi/processor/notifier/ue_context.go @@ -5,7 +5,7 @@ import ( "fmt" amf_context "github.com/free5gc/amf/internal/context" - "github.com/free5gc/openapi/Namf_Communication" + Namf_Communication "github.com/free5gc/openapi/amf/Communication" "github.com/free5gc/openapi/models" ) @@ -22,17 +22,18 @@ func SendN2InfoNotifyN2Handover(ue *amf_context.AmfUe, releaseList []int32) erro NotifyReason: models.N2InfoNotifyReason_HANDOVER_COMPLETED, } - _, httpResponse, err := client.N2MessageNotifyCallbackDocumentApiServiceCallbackDocumentApi. - N2InfoNotify(context.Background(), ue.HandoverNotifyUri, n2InformationNotification) + n2InformationNotificationReq := Namf_Communication.N2InfoNotifyHandoverCompleteRequest{ + N2InformationNotification: &n2InformationNotification, + } + + _, err := client.IndividualUeContextDocumentApi. + N2InfoNotifyHandoverComplete(context.Background(), ue.HandoverNotifyUri, &n2InformationNotificationReq) if err == nil { // TODO: handle Msg } else { - if httpResponse == nil { - HttpLog.Errorln(err.Error()) - } else if err.Error() != httpResponse.Status { - HttpLog.Errorln(err.Error()) - } + HttpLog.Errorln(err.Error()) + return err } return nil } diff --git a/internal/sbi/processor/subscription.go b/internal/sbi/processor/subscription.go index 43b9f30..0b598e1 100644 --- a/internal/sbi/processor/subscription.go +++ b/internal/sbi/processor/subscription.go @@ -12,7 +12,9 @@ import ( ) // TS 29.518 5.2.2.5.1 -func (p *Processor) HandleAMFStatusChangeSubscribeRequest(c *gin.Context, subscriptionDataReq models.SubscriptionData) { +func (p *Processor) HandleAMFStatusChangeSubscribeRequest(c *gin.Context, + subscriptionDataReq models.AmfCommunicationSubscriptionData, +) { logger.CommLog.Info("Handle AMF Status Change Subscribe Request") subscriptionDataRsp, locationHeader, problemDetails := p.AMFStatusChangeSubscribeProcedure(subscriptionDataReq) @@ -25,8 +27,9 @@ func (p *Processor) HandleAMFStatusChangeSubscribeRequest(c *gin.Context, subscr c.JSON(http.StatusCreated, subscriptionDataRsp) } -func (p *Processor) AMFStatusChangeSubscribeProcedure(subscriptionDataReq models.SubscriptionData) ( - subscriptionDataRsp models.SubscriptionData, locationHeader string, problemDetails *models.ProblemDetails, +func (p *Processor) AMFStatusChangeSubscribeProcedure(subscriptionDataReq models.AmfCommunicationSubscriptionData) ( + subscriptionDataRsp models.AmfCommunicationSubscriptionData, locationHeader string, + problemDetails *models.ProblemDetails, ) { amfSelf := context.GetSelf() @@ -84,7 +87,7 @@ func (p *Processor) AMFStatusChangeUnSubscribeProcedure(subscriptionID string) ( // TS 29.518 5.2.2.5.1.3 func (p *Processor) HandleAMFStatusChangeSubscribeModify(c *gin.Context, - updateSubscriptionData models.SubscriptionData, + updateSubscriptionData models.AmfCommunicationSubscriptionData, ) { logger.CommLog.Info("Handle AMF Status Change Subscribe Modify Request") @@ -101,8 +104,8 @@ func (p *Processor) HandleAMFStatusChangeSubscribeModify(c *gin.Context, } func (p *Processor) AMFStatusChangeSubscribeModifyProcedure(subscriptionID string, - subscriptionData models.SubscriptionData) ( - *models.SubscriptionData, *models.ProblemDetails, + subscriptionData models.AmfCommunicationSubscriptionData) ( + *models.AmfCommunicationSubscriptionData, *models.ProblemDetails, ) { amfSelf := context.GetSelf() diff --git a/internal/sbi/processor/ue_context.go b/internal/sbi/processor/ue_context.go index 6360704..5a9838f 100644 --- a/internal/sbi/processor/ue_context.go +++ b/internal/sbi/processor/ue_context.go @@ -24,14 +24,14 @@ func (p *Processor) HandleCreateUEContextRequest(c *gin.Context, createUeContext createUeContextResponse, ueContextCreateError := p.CreateUEContextProcedure(ueContextID, createUeContextRequest) if ueContextCreateError != nil { - c.JSON(int(ueContextCreateError.Error.Status), ueContextCreateError) + c.JSON(int(ueContextCreateError.JsonData.Error.Status), ueContextCreateError) } else { c.JSON(http.StatusCreated, createUeContextResponse) } } func (p *Processor) CreateUEContextProcedure(ueContextID string, createUeContextRequest models.CreateUeContextRequest) ( - *models.CreateUeContextResponse, *models.UeContextCreateError, + *models.CreateUeContextResponse201, *models.CreateUeContextResponse403, ) { amfSelf := context.GetSelf() ueContextCreateData := createUeContextRequest.JsonData @@ -39,12 +39,15 @@ func (p *Processor) CreateUEContextProcedure(ueContextID string, createUeContext if ueContextCreateData.UeContext == nil || ueContextCreateData.TargetId == nil || ueContextCreateData.PduSessionList == nil || ueContextCreateData.SourceToTargetData == nil || ueContextCreateData.N2NotifyUri == "" { - ueContextCreateError := &models.UeContextCreateError{ + ueCtxCreateError := models.UeContextCreateError{ Error: &models.ProblemDetails{ Status: http.StatusForbidden, Cause: "HANDOVER_FAILURE", }, } + ueContextCreateError := &models.CreateUeContextResponse403{ + JsonData: &ueCtxCreateError, + } return nil, ueContextCreateError } // create the UE context in target amf @@ -109,7 +112,7 @@ func (p *Processor) CreateUEContextProcedure(ueContextID string, createUeContext // ueContextCreateData.UeContext.MmContextList // ue.CurPduSession.PduSessionId = ueContextCreateData.UeContext.SessionContextList. // ue.TraceData = ueContextCreateData.UeContext.TraceData - createUeContextResponse := new(models.CreateUeContextResponse) + createUeContextResponse := new(models.CreateUeContextResponse201) createUeContextResponse.JsonData = &models.UeContextCreatedData{ UeContext: &models.UeContext{ Supi: ueContextCreateData.UeContext.Supi, @@ -196,11 +199,11 @@ func (p *Processor) ReleaseUEContextProcedure(ueContextID string, } func (p *Processor) HandleMobiRegUe(ue *context.AmfUe, ueContextTransferRspData *models.UeContextTransferRspData, - ueContextTransferResponse *models.UeContextTransferResponse, + ueContextTransferResponse *models.UeContextTransferResponse200, ) { ueContextTransferRspData.UeRadioCapability = &models.N2InfoContent{ NgapMessageType: 0, - NgapIeType: models.NgapIeType_UE_RADIO_CAPABILITY, + NgapIeType: models.AmfCommunicationNgapIeType_UE_RADIO_CAPABILITY, NgapData: &models.RefToBinaryData{ ContentId: "n2Info", }, @@ -227,7 +230,7 @@ func (p *Processor) HandleUEContextTransferRequest(c *gin.Context, func (p *Processor) UEContextTransferProcedure(ueContextID string, ueContextTransferRequest models.UeContextTransferRequest) ( - *models.UeContextTransferResponse, *models.ProblemDetails, + *models.UeContextTransferResponse200, *models.ProblemDetails, ) { amfSelf := context.GetSelf() @@ -262,7 +265,7 @@ func (p *Processor) UEContextTransferProcedure(ueContextID string, ue.Lock.Lock() defer ue.Lock.Unlock() - ueContextTransferResponse := &models.UeContextTransferResponse{ + ueContextTransferResponse := &models.UeContextTransferResponse200{ JsonData: new(models.UeContextTransferRspData), } ueContextTransferRspData := ueContextTransferResponse.JsonData @@ -473,19 +476,23 @@ func (p *Processor) buildUEContextModel(ue *context.AmfUe, reason models.Transfe return ueContext } -func (p *Processor) buildAmPolicyReqTriggers(triggers []models.RequestTrigger) ( - amPolicyReqTriggers []models.AmPolicyReqTrigger, +func (p *Processor) buildAmPolicyReqTriggers(triggers []models.PcfAmPolicyControlRequestTrigger) ( + amPolicyReqTriggers []models.PolicyReqTrigger, ) { for _, trigger := range triggers { switch trigger { - case models.RequestTrigger_LOC_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_LOCATION_CHANGE) - case models.RequestTrigger_PRA_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_PRA_CHANGE) - case models.RequestTrigger_SERV_AREA_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_SARI_CHANGE) - case models.RequestTrigger_RFSP_CH: - amPolicyReqTriggers = append(amPolicyReqTriggers, models.AmPolicyReqTrigger_RFSP_INDEX_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_LOC_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_LOCATION_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_PRA_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_PRA_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_ALLOWED_NSSAI_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_ALLOWED_NSSAI_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_NWDAF_DATA_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_NWDAF_DATA_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_SMF_SELECT_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_SMF_SELECT_CHANGE) + case models.PcfAmPolicyControlRequestTrigger_ACCESS_TYPE_CH: + amPolicyReqTriggers = append(amPolicyReqTriggers, models.PolicyReqTrigger_ACCESS_TYPE_CHANGE) } } return @@ -527,8 +534,9 @@ func (p *Processor) AssignEbiDataProcedure(ueContextID string, assignEbiData mod // TODO: AssignEbiError not used, check it! if _, okSmContextFind := ue.SmContextFindByPDUSessionID(assignEbiData.PduSessionId); okSmContextFind { - var assignedEbiData *models.AssignedEbiData - assignedEbiData.PduSessionId = assignEbiData.PduSessionId + assignedEbiData := &models.AssignedEbiData{ + PduSessionId: assignEbiData.PduSessionId, + } return assignedEbiData, nil, nil } logger.ProducerLog.Errorf("SmContext[PDU Session ID:%d] not found", assignEbiData.PduSessionId) @@ -584,7 +592,7 @@ func (p *Processor) RegistrationStatusUpdateProcedure(ueContextID string, if ueRegStatusUpdateReqData.TransferStatus == models.UeContextTransferStatus_TRANSFERRED { // remove the individual ueContext resource and release any PDU session(s) for _, pduSessionId := range ueRegStatusUpdateReqData.ToReleaseSessionList { - cause := models.Cause_REL_DUE_TO_SLICE_NOT_AVAILABLE + cause := models.SmfPduSessionCause_REL_DUE_TO_SLICE_NOT_AVAILABLE causeAll := &context.CauseAll{ Cause: &cause, } diff --git a/internal/sbi/routes.go b/internal/sbi/routes.go index 124bbf8..82767aa 100644 --- a/internal/sbi/routes.go +++ b/internal/sbi/routes.go @@ -3,6 +3,7 @@ package sbi import "github.com/gin-gonic/gin" type Route struct { + Name string Method string Pattern string APIFunc gin.HandlerFunc diff --git a/internal/sbi/server.go b/internal/sbi/server.go index 8cec3d0..c7b9e7e 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -113,6 +113,22 @@ func newRouter(s *Server) *gin.Engine { routerAuthorizationCheck.Check(c, amf_context.GetSelf()) }) applyRoutes(amfOAMGroup, amfOAMRoutes) + case models.ServiceName_NAMF_MBS_COMM: + amfMbsComGroup := router.Group(factory.AmfMbsComResUriPrefix) + amfMbsComRoutes := s.getMbsCommunicationRoutes() + routerAuthorizationCheck := util_oauth.NewRouterAuthorizationCheck(models.ServiceName_NAMF_MBS_COMM) + amfMbsComGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, amf_context.GetSelf()) + }) + applyRoutes(amfMbsComGroup, amfMbsComRoutes) + case models.ServiceName_NAMF_MBS_BC: + amfMbsBCGroup := router.Group(factory.AmfMbsBCResUriPrefix) + amfMbsBCRoutes := s.getMbsBroadcastRoutes() + routerAuthorizationCheck := util_oauth.NewRouterAuthorizationCheck(models.ServiceName_NAMF_MBS_BC) + amfMbsBCGroup.Use(func(c *gin.Context) { + routerAuthorizationCheck.Check(c, amf_context.GetSelf()) + }) + applyRoutes(amfMbsBCGroup, amfMbsBCRoutes) } } @@ -120,19 +136,6 @@ func newRouter(s *Server) *gin.Engine { } func (s *Server) Run(traceCtx context.Context, wg *sync.WaitGroup) error { - var profile models.NfProfile - if profileTmp, err1 := s.Consumer().BuildNFInstance(s.Context()); err1 != nil { - logger.InitLog.Error("Build AMF Profile Error") - } else { - profile = profileTmp - } - _, nfId, err_reg := s.Consumer().SendRegisterNFInstance(s.Context().NrfUri, s.Context().NfId, profile) - if err_reg != nil { - logger.InitLog.Warnf("Send Register NF Instance failed: %+v", err_reg) - } else { - s.Context().NfId = nfId - } - wg.Add(1) go s.startServer(wg) diff --git a/internal/util/convert.go b/internal/util/convert.go index 9573978..794197b 100644 --- a/internal/util/convert.go +++ b/internal/util/convert.go @@ -26,6 +26,14 @@ func SnssaiModelsToHex(snssai models.Snssai) string { return sst + snssai.Sd } +func SnssaiModelsToExtSnssai(snssai models.Snssai) models.ExtSnssai { + ExtStssai := models.ExtSnssai{ + Sst: snssai.Sst, + Sd: snssai.Sd, + } + return ExtStssai +} + func SeperateAmfId(amfid string) (regionId, setId, ptrId string, err error) { if len(amfid) != 6 { err = fmt.Errorf("len of amfId[%s] != 6", amfid) @@ -51,6 +59,12 @@ func PlmnIdStringToModels(plmnId string) (plmnID models.PlmnId) { return } +func PlmnIdNidToModelsPlmnId(plmnIdNid models.PlmnIdNid) (plmnId models.PlmnId) { + plmnId.Mcc = plmnIdNid.Mcc + plmnId.Mnc = plmnIdNid.Mnc + return +} + func TACConfigToModels(intString string) (hexString string) { tmp, err := strconv.ParseUint(intString, 10, 32) if err != nil { diff --git a/internal/util/search_nf_service.go b/internal/util/search_nf_service.go index 32d5e79..ef762a3 100644 --- a/internal/util/search_nf_service.go +++ b/internal/util/search_nf_service.go @@ -6,11 +6,11 @@ import ( "github.com/free5gc/openapi/models" ) -func SearchNFServiceUri(nfProfile models.NfProfile, serviceName models.ServiceName, +func SearchNFServiceUri(nfProfile *models.NrfNfDiscoveryNfProfile, serviceName models.ServiceName, nfServiceStatus models.NfServiceStatus, ) (nfUri string) { if nfProfile.NfServices != nil { - for _, service := range *nfProfile.NfServices { + for _, service := range nfProfile.NfServices { if service.ServiceName == serviceName && service.NfServiceStatus == nfServiceStatus { if nfProfile.Fqdn != "" { nfUri = nfProfile.Fqdn @@ -19,7 +19,7 @@ func SearchNFServiceUri(nfProfile models.NfProfile, serviceName models.ServiceNa } else if service.ApiPrefix != "" { nfUri = service.ApiPrefix } else if service.IpEndPoints != nil { - point := (*service.IpEndPoints)[0] + point := (service.IpEndPoints)[0] if point.Ipv4Address != "" { nfUri = getSbiUri(service.Scheme, point.Ipv4Address, point.Port) } else if len(nfProfile.Ipv4Addresses) != 0 { diff --git a/pkg/factory/config.go b/pkg/factory/config.go index ad70f4d..5cd9e3c 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -38,6 +38,8 @@ const ( AmfLocResUriPrefix = "/namf-loc/v1" AmfMtResUriPrefix = "/namf-mt/v1" AmfOamResUriPrefix = "/namf-oam/v1" + AmfMbsComResUriPrefix = "/namf-mbs-comm/v1" + AmfMbsBCResUriPrefix = "/namf-mbs-bc/v1" ) type Config struct { diff --git a/pkg/service/init.go b/pkg/service/init.go index 43b584f..6017298 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -137,6 +137,19 @@ func (a *AmfApp) Start() { a.wg.Add(1) go a.listenShutdownEvent() + var profile models.NrfNfManagementNfProfile + if profileTmp, err1 := a.Consumer().BuildNFInstance(a.Context()); err1 != nil { + logger.InitLog.Error("Build AMF Profile Error") + } else { + profile = profileTmp + } + _, nfId, err_reg := a.Consumer().SendRegisterNFInstance(a.ctx, a.Context().NrfUri, a.Context().NfId, &profile) + if err_reg != nil { + logger.InitLog.Warnf("Send Register NF Instance failed: %+v", err_reg) + } else { + a.Context().NfId = nfId + } + if err := a.sbiServer.Run(context.Background(), &a.wg); err != nil { logger.MainLog.Fatalf("Run SBI server failed: %+v", err) }