热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

本文分析Free5GCServicerequestprocedure业务请求流程1. UEContextReleaseRequest(NG-RANnodeinitiated)   

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

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

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

《【5G核心网】free5GC 业务请求流程源码分析》 Figure 8.3.2.2-1: UE context release request

    NGAP 消息, Present:NGAPPDUPresentInitiatingMessage,Procedure: ProcedureCodeUEContextReleaseRequest 

《【5G核心网】free5GC 业务请求流程源码分析》 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

《【5G核心网】free5GC 业务请求流程源码分析》 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())

《【5G核心网】free5GC 业务请求流程源码分析》 PFCP Session Modification Request

   1.5 AMF 发送 UE Context Release Command 

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

 

   1.6 发送 NGAP UE Context Release Complete

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

   1.7 HandleUEContextReleaseComplete 函数

    删除 UE 上下文

 

2. UE 发送 Service Request

    Gmm 消息类型设置为 MsgTypeServiceRequest

《【5G核心网】free5GC 业务请求流程源码分析》 NAS Table 8.2.16.1.1: SERVICE REQUEST message content

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

《【5G核心网】free5GC 业务请求流程源码分析》 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)

《【5G核心网】free5GC 业务请求流程源码分析》 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 隧道

《【5G核心网】free5GC 业务请求流程源码分析》 PFCP Session Modification Request

   5.1 SMF response AMF 

《【5G核心网】free5GC 业务请求流程源码分析》 SMF->AMF response UpdateSmContextActivateUpCnState

 

6. AMF 发送 Service Accept

《【5G核心网】free5GC 业务请求流程源码分析》 InitialContextSetupRequest,Service request

 

7. NGAP InitialContextSetupResponse

《【5G核心网】free5GC 业务请求流程源码分析》 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
// }
}
}

 


推荐阅读
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有