diff --git a/context/amf_ran.go b/context/amf_ran.go index bfae9e18..d52f10d3 100644 --- a/context/amf_ran.go +++ b/context/amf_ran.go @@ -161,7 +161,6 @@ func (ran *AmfRan) SetRanId(ranNodeId *ngapType.GlobalRANNodeID) { if ranId.GNbId != nil { ran.GnbId += ranId.GNbId.GNBValue } - AMF_Self().AmfRanPool.Store(ran.GnbId, ran) } func (ran *AmfRan) ConvertGnbIdToRanId(gnbId string) (ranNodeId *models.GlobalRanNodeId) { diff --git a/httpcallback/api_dereg_notify.go b/httpcallback/api_dereg_notify.go new file mode 100644 index 00000000..accc2d7e --- /dev/null +++ b/httpcallback/api_dereg_notify.go @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: 2022 Infosys Limited +// Copyright 2019 free5GC.org +// +// SPDX-License-Identifier: Apache-2.0 +// + +package httpcallback + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/omec-project/amf/logger" + "github.com/omec-project/amf/producer" + "github.com/omec-project/openapi" + "github.com/omec-project/openapi/models" + "github.com/omec-project/util/httpwrapper" +) + +func HTTPDeregistrationNotification(c *gin.Context) { + var deregistrationData models.DeregistrationData + + 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(&deregistrationData, requestBody, "application/json") + if err != nil { + problemDetail := "[Request Body] " + err.Error() + rsp := models.ProblemDetails{ + Title: "Malformed request syntax", + Status: http.StatusBadRequest, + Detail: problemDetail, + } + logger.CallbackLog.Errorln(problemDetail) + c.JSON(http.StatusBadRequest, rsp) + return + } + + req := httpwrapper.NewRequest(c.Request, deregistrationData) + if supi, exists := c.Params.Get("supi"); exists { + req.Params["supi"] = supi + } + rsp := producer.HandleDeregistrationNotification(req) + + responseBody, err := openapi.Serialize(rsp.Body, "application/json") + if err != nil { + logger.CallbackLog.Errorln(err) + problemDetails := models.ProblemDetails{ + Status: http.StatusInternalServerError, + Cause: "SYSTEM_FAILURE", + Detail: err.Error(), + } + c.JSON(http.StatusInternalServerError, problemDetails) + } else { + c.Data(rsp.Status, "application/json", responseBody) + } + +} diff --git a/httpcallback/router.go b/httpcallback/router.go index 2b26dd07..5fd82595 100644 --- a/httpcallback/router.go +++ b/httpcallback/router.go @@ -109,4 +109,10 @@ var routes = Routes{ "/nf-status-notify", HTTPNfSubscriptionStatusNotify, }, + { + "DeregistrationNotify", + strings.ToUpper("Post"), + ":supi/deregistration-notify", + HTTPDeregistrationNotification, + }, } diff --git a/producer/callback.go b/producer/callback.go index 414e4470..639c1f70 100644 --- a/producer/callback.go +++ b/producer/callback.go @@ -493,3 +493,52 @@ func NfSubscriptionStatusNotifyProcedure(notificationData models.NotificationDat return nil } + +func HandleDeregistrationNotification(request *httpwrapper.Request) *httpwrapper.Response { + logger.ProducerLog.Infoln("Handle Deregistration Notification") + deregistrationData := request.Body.(models.DeregistrationData) + + switch deregistrationData.DeregReason { + case "SUBSCRIPTION_WITHDRAWN": + amfSelf := context.AMF_Self() + if supi, exists := request.Params["supi"]; exists { + reqUri := request.URL.RequestURI() + if ue, ok := amfSelf.AmfUeFindBySupi(supi); ok { + logger.ProducerLog.Debugln("amf ue found: ", ue.Supi) + sbiMsg := context.SbiMsg{ + UeContextId: ue.Supi, + ReqUri: reqUri, + Msg: nil, + Result: make(chan context.SbiResponseMsg, 10), + } + ue.EventChannel.UpdateSbiHandler(HandleOAMPurgeUEContextRequest) + ue.EventChannel.SubmitMessage(sbiMsg) + msg := <-sbiMsg.Result + if msg.ProblemDetails != nil { + return httpwrapper.NewResponse(int(msg.ProblemDetails.(*models.ProblemDetails).Status), nil, msg.ProblemDetails.(*models.ProblemDetails)) + } else { + return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) + } + } else { + return httpwrapper.NewResponse(http.StatusNotFound, nil, nil) + } + } + + case "": + problemDetails := &models.ProblemDetails{ + Status: http.StatusBadRequest, + Cause: "MANDATORY_IE_MISSING", // Defined in TS 29.503 6.2.5.2 + Detail: "Missing IE [DeregReason] in DeregistrationData", + } + return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + + default: + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotImplemented, + Cause: "NOT_IMPLEMENTED", // Defined in TS 29.503 + Detail: "Unsupported [DeregReason] in DeregistrationData", + } + return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + } + return nil +}