【5G核心网】free5GC 业务请求流程源码分析

本文分析 Free5GC Service request procedure 业务请求流程

1. UE Context Release Request (NG-RAN node initiated)

    UE上下文释放请求过程的目的是由于 NG-RAN 节点的原因,请求 AMF 释放与 UE 相关的逻辑 NG 连接。该过程使用 UE 相关的信令。UE 上下文释放请求消息应指示释放的适当原因值,例如“ TXnRELOCOverall Expiry”,“ Redirection”。

Figure 8.3.2.2-1: UE context release request

    NGAP 消息, Present:NGAPPDUPresentInitiatingMessage,Procedure: ProcedureCodeUEContextReleaseRequest 

UEContextReleaseRequest

   1.1 AMF 处理 UE Context Release Request 

    NGAP.Dispatch

       -->  HandleUEContextReleaseRequest

     如果 ue 在 AMF 状态是已经注册的, PDU 会话资源列表不空,则 SendUpdateSmContextDeactivateUpCnxState 更新上下文 Deactivate 状态

if amfUe.State[ran.AnType].Is(context.Registered) {
	Ngaplog.Info("[NGAP] Ue Context in GMM-Registered")
	if pDUSessionResourceList != nil {
		for _, pduSessionReourceItem := range pDUSessionResourceList.List {
			pduSessionID := int32(pduSessionReourceItem.PDUSessionID.Value)
			response, _, _, err := consumer.SendUpdateSmContextDeactivateUpCnxState(amfUe, pduSessionID, causeAll)
			if err != nil {
				logger.NgapLog.Errorf("Send Update SmContextDeactivate UpCnxState Error[%s]", err.Error())
			} else if response == nil {
				logger.NgapLog.Errorln("Send Update SmContextDeactivate UpCnxState Error")
			}
		}
	}

    如果 ue 在 AMF 是未注册,则释放上下文

Ngaplog.Info("[NGAP] Ue Context in Non GMM-Registered")
for pduSessionId := range amfUe.SmContextList {
	releaseData := consumer.BuildReleaseSmContextRequest(amfUe, &causeAll, "", nil)
	detail, err := consumer.SendReleaseSmContextRequest(amfUe, pduSessionId, releaseData)
	if err != nil {
		logger.NgapLog.Errorf("Send ReleaseSmContextRequest Error[%s]", err.Error())
	} else if detail != nil {
		logger.NgapLog.Errorf("Send ReleaseSmContextRequeste Error[%s]", detail.Cause)
	}
}
ngap_message.SendUEContextReleaseCommand(ranUe, context.UeContextReleaseUeContext, causeGroup, causeValue)
return

   1.2 SendUpdateSmContextDeactivateUpCnxState 函数

    BuildUpdateSmContextRequest 函数更新 SmContextUpdateData,SMF API 为 /sm-contexts/{smContextRef}/modify

AMF->SMF UpdateSmContext 请求

   1.3 SMF 处理 UpdateSmContextDeactive

func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmContextRequest) *http_wrapper.Response {
	//GSM State
	//PDU Session Modification Reject(Cause Value == 43 || Cause Value != 43)/Complete
	//PDU Session Release Command/Complete
	logger.PduSessLog.Infoln("In HandlePDUSessionSMContextUpdate")
	smContext := smf_context.GetSMContext(smContextRef)

    既不包含 N1 也不包含 N2 信息,简单多了,UpCnxState 为 Deactivated

case models.UpCnxState_DEACTIVATED:
	if smContext.SMContextState != smf_context.Active {
		//Wait till the state becomes Active again
		//TODO: implement sleep wait in concurrent architecture
		logger.PduSessLog.Infoln("The SMContext State should be Active State")
		logger.PduSessLog.Infoln("SMContext state: ", smContext.SMContextState.String())
	}
	smContext.SMContextState = smf_context.ModificationPending
	logger.CtxLog.Traceln("SMContextState Change State: ", smContext.SMContextState.String())
	response.JsonData.UpCnxState = models.UpCnxState_DEACTIVATED
	smContext.UpCnxState = body.JsonData.UpCnxState
	smContext.UeLocation = body.JsonData.UeLocation

   1.4 SMF 释放 N3,主要就是 FAR

// TODO: Deactivate N2 downlink tunnel
//Set FAR and An, N3 Release Info
farList = []*smf_context.FAR{}
smContext.PendingUPF = make(smf_context.PendingUPF)
for _, dataPath := range smContext.Tunnel.DataPathPool {

	ANUPF := dataPath.FirstDPNode
	DLPDR := ANUPF.DownLinkTunnel.PDR
	if DLPDR == nil {
		logger.PduSessLog.Errorf("AN Release Error")
	} else {
		DLPDR.FAR.State = smf_context.RULE_UPDATE
		DLPDR.FAR.ApplyAction.Forw = false
		DLPDR.FAR.ApplyAction.Buff = true
		DLPDR.FAR.ApplyAction.Nocp = true
		smContext.PendingUPF[ANUPF.GetNodeIP()] = true
	}

	farList = append(farList, DLPDR.FAR)
}

sendPFCPModification = true
smContext.SMContextState = smf_context.PFCPModification
logger.CtxLog.Traceln("SMContextState Change State: ", smContext.SMContextState.String())
PFCP Session Modification Request

   1.5 AMF 发送 UE Context Release Command 

UEContextReleaseCommand

 

   1.6 发送 NGAP UE Context Release Complete

UEContextReleaseComplete

   1.7 HandleUEContextReleaseComplete 函数

    删除 UE 上下文

 

2. UE 发送 Service Request

    Gmm 消息类型设置为 MsgTypeServiceRequest

NAS Table 8.2.16.1.1: SERVICE REQUEST message content

    NGAP 消息设置 Present 为 NGAPPDUPresentInitiatingMessage,ProcedureCode 为 ProcedureCodeInitialUEMessage

InitialUEMEssage, Service request

3. AMF 处理 Service Request 

func HandleInitialUEMessage(ran *context.AmfRan, message *ngapType.NGAPPDU) {

	amfSelf := context.AMF_Self()

	var rANUENGAPID *ngapType.RANUENGAPID
	var nASPDU *ngapType.NASPDU
	var userLocationInformation *ngapType.UserLocationInformation
	var rRCEstablishmentCause *ngapType.RRCEstablishmentCause
	var fiveGSTMSI *ngapType.FiveGSTMSI
	// var aMFSetID *ngapType.AMFSetID
	var uEContextRequest *ngapType.UEContextRequest
	// var allowedNSSAI *ngapType.AllowedNSSAI

   3.1 UE 上下文在 AMF 已经被清除

if ranUe == nil {
	var err error
	ranUe, err = ran.NewRanUe(rANUENGAPID.Value)
	if err != nil {
		logger.NgapLog.Errorf("NewRanUe Error: %+v", err)
	}
	Ngaplog.Debugf("New RanUe [RanUeNgapID: %d]", ranUe.RanUeNgapId)

	if fiveGSTMSI != nil {
		Ngaplog.Debug("Receive 5G-S-TMSI")

		servedGuami := amfSelf.ServedGuamiList[0]

 

4. HandleServiceRequest 函数

// TS 24501 5.6.1
func HandleServiceRequest(ue *context.AmfUe, anType models.AccessType,
	serviceRequest *nasMessage.ServiceRequest) error {
	logger.GmmLog.Info("Handle Service Reqeust")

	if ue == nil {
		return fmt.Errorf("AmfUe is nil")
	}

	util.StopT3513(ue)
	util.StopT3565(ue)

   4.1 处理 UplinkDataStatus 

    SendUpdateSmContextActivateUpCnState 函数向 SMF 发送激活会话上下文请求

if serviceRequest.UplinkDataStatus != nil {
	uplinkDataPsi := nasConvert.PSIToBooleanArray(serviceRequest.UplinkDataStatus.Buffer)
	reactivationResult = new([16]bool)
	for pduSessionId, smContext := range ue.SmContextList {
		if pduSessionId == targetPduSessionId {
			continue
		}
		if uplinkDataPsi[pduSessionId] && smContext.PduSessionContext.AccessType == models.AccessType__3_GPP_ACCESS {
			response, errRes, _, err := consumer.SendUpdateSmContextActivateUpCnxState(
				ue, pduSessionId, models.AccessType__3_GPP_ACCESS)
AMF-SMF UpdateSmContextActivateUpCnState

 

5. SMF 处理函数 HandlePDUSessionSMContextUpdate

func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmContextRequest) *http_wrapper.Response {
	//GSM State
	//PDU Session Modification Reject(Cause Value == 43 || Cause Value != 43)/Complete
	//PDU Session Release Command/Complete
	logger.PduSessLog.Infoln("In HandlePDUSessionSMContextUpdate")
	smContext := smf_context.GetSMContext(smContextRef)

    根据 N2 会话信息类型为 N2SmInfoType_PDU_RES_SETUP_RSP

switch smContextUpdateData.N2SmInfoType {
case models.N2SmInfoType_PDU_RES_SETUP_RSP:
	if smContext.SMContextState != smf_context.Active {
		//Wait till the state becomes Active again
		//TODO: implement sleep wait in concurrent architecture
		logger.PduSessLog.Infoln("The SMContext State should be Active State")
		logger.PduSessLog.Infoln("SMContext state: ", smContext.SMContextState.String())
	}
	smContext.SMContextState = smf_context.ModificationPending
	logger.CtxLog.Traceln("SMContextState Change State: ", smContext.SMContextState.String())
	pdrList = []*smf_context.PDR{}
	farList = []*smf_context.FAR{}

   SMF 向 UPF 发送 PFCP Session Modification Request 将 N3 RAN 与 UPF 建立 GTP 隧道

PFCP Session Modification Request

   5.1 SMF response AMF 

SMF->AMF response UpdateSmContextActivateUpCnState

 

6. AMF 发送 Service Accept

InitialContextSetupRequest,Service request

 

7. NGAP InitialContextSetupResponse

NGAP InitialContextSetupResponse

 

8. AMF 函数 HandleInitialContextSetupResponse

   根据 PDU 会话资源列表更新发向 SMF,这里不分析了,还有 SMF 向 UPF 更新

if pDUSessionResourceSetupResponseList != nil {
	Ngaplog.Trace("[NGAP] Send PDUSessionResourceSetupResponseTransfer to SMF")

	for _, item := range pDUSessionResourceSetupResponseList.List {
		pduSessionID := int32(item.PDUSessionID.Value)
		transfer := item.PDUSessionResourceSetupResponseTransfer

		// response, _, _, err := consumer.SendUpdateSmContextN2Info(amfUe, pduSessionID,
		_, _, _, err := consumer.SendUpdateSmContextN2Info(amfUe, pduSessionID,
			models.N2SmInfoType_PDU_RES_SETUP_RSP, transfer)
		if err != nil {
			Ngaplog.Errorf("SendUpdateSmContextN2Info[PDUSessionResourceSetupResponseTransfer] Error:\n%s", err.Error())
		}
		// RAN initiated QoS Flow Mobility in subclause 5.2.2.3.7
		// if response != nil && response.BinaryDataN2SmInformation != nil {
		// TODO: n2SmInfo send to RAN
		// } else if response == nil {
		// TODO: error handling
		// }
	}
}

 

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值