Skip to content

Commit

Permalink
Modify HTTPHandleDeregistrationNotification
Browse files Browse the repository at this point in the history
* Modify the structure of the handler function.
* Add query parameter to differential the deregistration type is implicit or explicit.
  • Loading branch information
YouShengLiu committed Sep 21, 2023
1 parent 3844928 commit 06e5c0a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 80 deletions.
7 changes: 3 additions & 4 deletions internal/sbi/consumer/ue_context_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func UeCmRegistration(ue *amf_context.AmfUe, accessType models.AccessType, initi

switch accessType {
case models.AccessType__3_GPP_ACCESS:
deregCallbackUri := fmt.Sprintf("%s%s/amf-implicit-deregistration/3gpp-access/%s",
deregCallbackUri := fmt.Sprintf("%s%s/deregistration/%s",
amfSelf.GetIPv4Uri(),
factory.AmfCallbackResUriPrefix,
ue.Supi,
Expand Down Expand Up @@ -107,9 +107,8 @@ func UeCmDeregistration(ue *amf_context.AmfUe, accessType models.AccessType) (
switch accessType {
case models.AccessType__3_GPP_ACCESS:
modificationData := models.Amf3GppAccessRegistrationModification{
Guami: &amfSelf.ServedGuamiList[0],
PurgeFlag: true,
BackupAmfInfo: ue.BackupAmfInfo,
Guami: &amfSelf.ServedGuamiList[0],
PurgeFlag: true,
}

httpResp, localErr := client.ParameterUpdateInTheAMFRegistrationFor3GPPAccessApi.Update(context.Background(),
Expand Down
158 changes: 85 additions & 73 deletions internal/sbi/httpcallback/api_handle_dereg_notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import (
"github.com/free5gc/openapi/models"
)

func HTTPAmfHandleDeregistrationNotification(c *gin.Context) {
func HTTPHandleDeregistrationNotification(c *gin.Context) {
// TS 23.502 - 4.2.2.2.2 - step 14d
logger.CallbackLog.Infoln("Handle Deregistration Notification")

var deregData models.DeregistrationData
var doUecmDereg bool = true

requestBody, err := c.GetRawData()
if err != nil {
Expand All @@ -34,105 +33,118 @@ func HTTPAmfHandleDeregistrationNotification(c *gin.Context) {

err = openapi.Deserialize(&deregData, requestBody, "application/json")
if err != nil {
problemDetails := "[Request Body] " + err.Error()
rsp := models.ProblemDetails{
problemDetails := models.ProblemDetails{
Title: "Malformed request syntax",
Status: http.StatusBadRequest,
Detail: problemDetails,
Detail: "[Request Body] " + err.Error(),
}
logger.CallbackLog.Errorln(problemDetails)
c.JSON(http.StatusBadRequest, rsp)
logger.CallbackLog.Errorln(problemDetails.Detail)
c.JSON(http.StatusBadRequest, problemDetails)
return
}

ueid := c.Param("ueid")
amfSelf := amf_context.GetSelf()
ue, ok := amfSelf.AmfUeFindByUeContextID(ueid)
deregType := c.Query("type")
ue, ok := amf_context.GetSelf().AmfUeFindByUeContextID(ueid)
if !ok {
logger.CallbackLog.Errorf("AmfUe Context[%s] not found", ueid)
problemDetails := &models.ProblemDetails{
problemDetails := models.ProblemDetails{
Status: http.StatusNotFound,
Cause: "CONTEXT_NOT_FOUND",
}
c.JSON(http.StatusNotFound, problemDetails)
return
}

switch deregData.DeregReason {
case models.DeregistrationReason_UE_INITIAL_REGISTRATION:
// TS 23.502 - 4.2.2.2.2 General Registration
// Invokes the Nsmf_PDUSession_ReleaseSMContext for the corresponding access type
ue.SmContextList.Range(func(key, value interface{}) bool {
smContext := value.(*amf_context.SmContext)
problemDetails, err := DeregistrationNotificationProcedure(ue, deregType, deregData)
if problemDetails != nil {
ue.GmmLog.Errorf("Deregistration Notification Procedure Failed Problem[%+v]", problemDetails)
} else if err != nil {
ue.GmmLog.Errorf("Deregistration Notification Procedure Error[%v]", err.Error())
}
// TS 23.503 - 5.3.2.3.2 UDM initiated NF Deregistration
// The AMF acknowledges the Nudm_UECM_DeRegistrationNotification to the UDM.
c.JSON(http.StatusNoContent, nil)
}

// TS 23.502 - 4.2.2.3.3 Network-initiated Deregistration
// The AMF can initiate this procedure for either explicit (e.g. by O&M intervention) or
// implicit (e.g. expiring of Implicit Deregistration timer)
func DeregistrationNotificationProcedure(ue *amf_context.AmfUe, deregType string, deregData models.DeregistrationData) (
problemDetails *models.ProblemDetails, err error,
) {
var doUecmDereg bool = true

if smContext.AccessType() == deregData.AccessType {
var problemDetails *models.ProblemDetails
problemDetails, err = consumer.SendReleaseSmContextRequest(ue, smContext, nil, "", nil)
if problemDetails != nil {
ue.GmmLog.Errorf("Release SmContext Failed Problem[%+v]", problemDetails)
} else if err != nil {
ue.GmmLog.Errorf("Release SmContext Error[%v]", err.Error())
if deregType == "implicit" {
// The AMF does not send the Deregistration Request message to the UE for Implicit Deregistration.
switch deregData.DeregReason {
case models.DeregistrationReason_UE_INITIAL_REGISTRATION:
// TS 23.502 - 4.2.2.2.2 General Registration
// Invokes the Nsmf_PDUSession_ReleaseSMContext for the corresponding access type
ue.SmContextList.Range(func(key, value interface{}) bool {
smContext := value.(*amf_context.SmContext)
if smContext.AccessType() == deregData.AccessType {
problemDetails, err = consumer.SendReleaseSmContextRequest(ue, smContext, nil, "", nil)
if problemDetails != nil {
ue.GmmLog.Errorf("Release SmContext Failed Problem[%+v]", problemDetails)
} else if err != nil {
ue.GmmLog.Errorf("Release SmContext Error[%v]", err.Error())
}
}
return true
})
case models.DeregistrationReason_SUBSCRIPTION_WITHDRAWN:
// The notification is triggered by the new AMF executing UECM registration,
// UDM will use the new data to replace the old context.
// Therefore old AMF doesn't need to execute UECM de-registration to clean the old context stored in UDM.
doUecmDereg = false
}
// TS 23.502 - 4.2.2.2.2 General Registration - 14e
// TODO: (R16) If old AMF does not have UE context for another access type (i.e. non-3GPP access),
// the Old AMF unsubscribes with the UDM for subscription data using Nudm_SDM_unsubscribe
if ue.SdmSubscriptionId != "" {
problemDetails, err = consumer.SDMUnsubscribe(ue)
if problemDetails != nil {
logger.GmmLog.Errorf("SDM Unubscribe Failed Problem[%+v]", problemDetails)
} else if err != nil {
logger.GmmLog.Errorf("SDM Unubscribe Error[%+v]", err)
}

return true
})
case models.DeregistrationReason_SUBSCRIPTION_WITHDRAWN:
// The notification is triggered by the new AMF executing UECM registration,
// UDM will use the new data to replace the old context.
// Therefore old AMF doesn't need to execute UECM de-registration to clean the old context stored in UDM.
doUecmDereg = false
}
// TS 23.502 - 4.2.2.2.2 General Registration - 14e
// TODO: (R16) If old AMF does not have UE context for another access type (i.e. non-3GPP access),
// the Old AMF unsubscribes with the UDM for subscription data using Nudm_SDM_unsubscribe
if ue.SdmSubscriptionId != "" {
var problemDetails *models.ProblemDetails
problemDetails, err = consumer.SDMUnsubscribe(ue)
if problemDetails != nil {
logger.GmmLog.Errorf("SDM Unubscribe Failed Problem[%+v]", problemDetails)
} else if err != nil {
logger.GmmLog.Errorf("SDM Unubscribe Error[%+v]", err)
ue.SdmSubscriptionId = ""
}
ue.SdmSubscriptionId = ""
}

if doUecmDereg {
// Use old AMF as the backup AMF
backupAmfInfo := models.BackupAmfInfo{
BackupAmf: amfSelf.Name,
GuamiList: amfSelf.ServedGuamiList,
if doUecmDereg {
if ue.UeCmRegistered[deregData.AccessType] {
problemDetails, err := consumer.UeCmDeregistration(ue, deregData.AccessType)
if problemDetails != nil {
logger.GmmLog.Errorf("UECM Deregistration Failed Problem[%+v]", problemDetails)
} else if err != nil {
logger.GmmLog.Errorf("UECM Deregistration Error[%+v]", err)
}
ue.UeCmRegistered[deregData.AccessType] = false
}
}
ue.UpdateBackupAmfInfo(backupAmfInfo)

if ue.UeCmRegistered[deregData.AccessType] {
problemDetails, err := consumer.UeCmDeregistration(ue, deregData.AccessType)
// TS 23.502 - 4.2.2.2.2 General Registration - 20
if ue.PolicyAssociationId != "" {
// TODO: It also needs to check if the PCF ID is tranfered to new AMF
// Currently, old AMF will transfer the PCF ID but new AMF will not utilize the PCF ID
problemDetails, err := consumer.AMPolicyControlDelete(ue)
if problemDetails != nil {
logger.GmmLog.Errorf("UECM Deregistration Failed Problem[%+v]", problemDetails)
logger.GmmLog.Errorf("Delete AM policy Failed Problem[%+v]", problemDetails)
} else if err != nil {
logger.GmmLog.Errorf("UECM Deregistration Error[%+v]", err)
logger.GmmLog.Errorf("Delete AM policy Error[%+v]", err)
}
ue.UeCmRegistered[deregData.AccessType] = false
}
}

// TS 23.502 - 4.2.2.2.2 General Registration - 20
if ue.PolicyAssociationId != "" {
// TODO: It also needs to check if the PCF ID is tranfered to new AMF
// Currently, old AMF will transfer the PCF ID but new AMF will not utilize the PCF ID
problemDetails, err := consumer.AMPolicyControlDelete(ue)
if problemDetails != nil {
logger.GmmLog.Errorf("Delete AM policy Failed Problem[%+v]", problemDetails)
} else if err != nil {
logger.GmmLog.Errorf("Delete AM policy Error[%+v]", err)
}
// The old AMF should clean the UE context
// TODO: (R16) Only remove the target access UE context
ue.Remove()
} else if deregType == "explicit" {
// TODO: TS 23.502 - 4.2.2.3.3 Network-initiated Deregistration
// AMF may need to send Deregistration Request message to the UE.
} else {
logger.CallbackLog.Errorf("Deregistration Notification Procedure: unknown deregistration type: %v", deregType)
}

// The old AMF should clean the UE context
// TODO: (R16) Only remove the target access UE context
ue.Remove()

// TS 23.503 - 5.3.2.3.2 UDM initiated NF Deregistration
// The AMF acknowledges the Nudm_UECM_DeRegistrationNotification to the UDM.
c.JSON(http.StatusNoContent, nil)
return nil, nil
}
6 changes: 3 additions & 3 deletions internal/sbi/httpcallback/routers.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ var routes = Routes{
},

{
"AmfHandleDeregistrationNotification",
"HandleDeregistrationNotification",
strings.ToUpper("Post"),
"/amf-implicit-deregistration/3gpp-access/:ueid",
HTTPAmfHandleDeregistrationNotification,
"/deregistration/:ueid",
HTTPHandleDeregistrationNotification,
},
}

0 comments on commit 06e5c0a

Please sign in to comment.