Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should be Supi not Guti in CreateUEContextRequest #146

Open
ruiqizhu-ricky opened this issue Dec 5, 2024 · 1 comment · May be fixed by #149
Open

Should be Supi not Guti in CreateUEContextRequest #146

ruiqizhu-ricky opened this issue Dec 5, 2024 · 1 comment · May be fixed by #149

Comments

@ruiqizhu-ricky
Copy link

ruiqizhu-ricky commented Dec 5, 2024

When I read the source code, I found that during the procedure of "inter NG-RAN node N2 based handover", the source AMF invokes CreateUEContextRequest of the target AMF, and passes the GUTI as the ueContextId in the code, which I believe should be the SUPI, or otherwise the target AMF will use GUTI as the key to store the newly created UeContext in AMFContext.UePool, which is incorrectly identified.

Here the the caller function of the source AMF

// https://github.com/free5gc/amf/blob/v1.2.6/internal/sbi/consumer/amf_service.go#L164
func (s *namfService) CreateUEContextRequest(ue *amf_context.AmfUe, ueContextCreateData models.UeContextCreateData) (
	ueContextCreatedData *models.UeContextCreatedData, problemDetails *models.ProblemDetails, err error,
) {
	res, httpResp, localErr := client.IndividualUeContextDocumentApi.CreateUEContext(ctx, ue.Guti, req)  // Guti?!!
}

// https://github.com/free5gc/openapi/blob/v1.0.8/Namf_Communication/api_individual_ue_context_document.go#L38
func (a *IndividualUeContextDocumentApiService) CreateUEContext(ctx context.Context, ueContextId string, createUeContextRequest models.CreateUeContextRequest) {
	// create path and map variables
	localVarPath := a.client.cfg.BasePath() + "/ue-contexts/{ueContextId}"
	localVarPath = strings.Replace(localVarPath, "{"+"ueContextId"+"}", fmt.Sprintf("%v", ueContextId), -1)
    // ......
}

Here is the CreateUeContext operation of the target AMF

// https://github.com/free5gc/amf/blob/v1.2.6/internal/sbi/processor/ue_context.go#L136
func (p *Processor) HandleCreateUEContextRequest(c *gin.Context, createUeContextRequest models.CreateUeContextRequest) {
	ueContextID := c.Param("ueContextId")
	createUeContextResponse, ueContextCreateError := p.CreateUEContextProcedure(ueContextID, createUeContextRequest)
	c.JSON(http.StatusCreated, createUeContextResponse)	
}

// https://github.com/free5gc/amf/blob/v1.2.6/internal/sbi/processor/ue_context.go#L33C1-L133C2
func (p *Processor) CreateUEContextProcedure(ueContextID string, 
    createUeContextRequest models.CreateUeContextRequest) (
	*models.CreateUeContextResponse, *models.UeContextCreateError,
) {
	amfSelf := context.GetSelf()
	ueContextCreateData := createUeContextRequest.JsonData
	ue := amfSelf.NewAmfUe(ueContextID)        // create the UE context in target amf
	ue.HandoverNotifyUri = ueContextCreateData.N2NotifyUri
}

// https://github.com/free5gc/amf/blob/v1.2.6/internal/context/context.go#L304C1-L316C2
func (context *AMFContext) NewAmfUe(supi string) *AmfUe {
	ue := AmfUe{}
	ue.init()
	if supi != "" {
		context.AddAmfUeToUePool(&ue, supi)
	}
	context.AllocateGutiToUe(&ue)
	logger.CtxLog.Infof("New AmfUe [supi:%s][guti:%s]", supi, ue.Guti)
	return &ue
}

func (context *AMFContext) AddAmfUeToUePool(ue *AmfUe, supi string) {
	if len(supi) == 0 {
		logger.CtxLog.Errorf("Supi is nil")
	}
	ue.Supi = supi
	context.UePool.Store(ue.Supi, ue)
}

Even in [email protected], the procedure description uses SUPI instead of GUTI.

[Conditional] S-AMF to T-AMF: Namf_Communication_CreateUEContext Request (N2 Information (Target
ID, Source to Target transparent container, SM N2 information list, PDU Session IDs), UE context information
(SUPI, Service area restriction, Allowed NSSAI for each Access Type and Partially Allowed NSSAI if available,
Tracing Requirements, LTE M Indication, the list of PDU Session IDs along with the corresponding SMF
information and the corresponding S-NSSAI(s), PCF ID(s), DNN, UE Radio Capability ID and UE Radio
Capability Information, N2 Notify URI). If the subscription information includes Tracing Requirements, the old
AMF provides the target AMF with Tracing Requirements.

I shall confess that I don't have the resource to actually run this procedure and check the code logic. I just feel like here is something wrong. But I also think experiments cannot be conducted as the handover between different AMF procedure is not yet implemented.

func handleHandoverRequiredMain(ran *context.AmfRan,
	sourceUe *context.RanUe,
	handoverType *ngapType.HandoverType,
	cause *ngapType.Cause,
	targetID *ngapType.TargetID,
	pDUSessionResourceListHORqd *ngapType.PDUSessionResourceListHORqd,
	sourceToTargetTransparentContainer *ngapType.SourceToTargetTransparentContainer,
) {
    // ......
    if !ok {
		// handover between different AMF
		sourceUe.Log.Warnf("Handover required : cannot find target Ran Node Id[%+v] in this AMF", targetRanNodeId)
		sourceUe.Log.Error("Handover between different AMF has not been implemented yet")
		return
		// TODO: Send to T-AMF
		// Described in (23.502 4.9.1.3.2) step 3.Namf_Communication_CreateUEContext Request
    }
    // ......
}	

Please correct me if I made mistakes.

@reki9185
Copy link
Contributor

Thank you for highlighting this issue; it should be SUPI, not GUTI.
We will correct it in the future version.

@reki9185 reki9185 linked a pull request Jan 21, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants