【5G核心网】free5GC 业务请求流程源码分析_ue context release request-程序员宅基地

技术标签: 5G  

本文分析 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
		// }
	}
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhonglinzhang/article/details/107841958

智能推荐

20172319 2018.10.19《Java程序设计教程》第7周课堂实践(补写博客)-程序员宅基地

文章浏览阅读240次。20172319 2018.10.19 《Java程序设计教程》第7周课堂实践课程:《程序设计与数据结构》班级:1723学生:唐才铭学号:20172319指导老师:王志强日期:2018.10.19必修/选修:必修目录测试内容测试要求实验步骤需求分析相关知识实现及解释错误分析参考资料测试内容三种查找算法练习:给定关键字序列:11,..._第六次作业 92给定关键字序列{ 11,78, 10, 1,3,2,4,21},分别用顺序查找、折半查找

linux命令j---jobs_jjob命令-程序员宅基地

文章浏览阅读290次。jobs------------查看在后台执行的进程fg %n----------将后台执行进程n调到前台执行,n表示jobnumber(通过jobs查看的进程编号,而非pid)ctrl+z----------将在前台执行的进程,放到后台并挂起bg %n---------将在后台挂起的进程,继续执行ctrl+c----------前台进程终止kill %n---------杀掉后台运行的..._jjob命令

顺序表、链表相关OJ题(1)-程序员宅基地

文章浏览阅读9.6k次,点赞128次,收藏118次。本文为经典算法OJ题练习,大部分题型都有多种思路,每种思路的解法博主都试过了(去网站那里验证)是正确的,大家可以参考!!

拦截驱动加载_pimage_nt_headers64 pntheaders64 = (pimage_nt_head-程序员宅基地

文章浏览阅读1.5k次。思路简单粗暴,直接注册一个模块监听,然后当目标驱动加载时hook它的驱动加载函数,直接返回成功,对付一下比较简单的驱动保护效果屡试不爽获取DriverEntryPVOID GetDriverEntryByImageBase(PVOID ImageBase){ PIMAGE_DOS_HEADER pDOSHeader; PIMAGE_NT_HEADERS64 pNTHeader; PVOID pEntryPoint; pDOSHeader = (PIMAGE_DOS_HEADER)ImageB_pimage_nt_headers64 pntheaders64 = (pimage_nt_headers64)((ulong64)hmod + pdo

@ConfigurationProperties和@ConditionalOnProperties的理解与使用_configurationonproperties-程序员宅基地

文章浏览阅读7.1k次,点赞6次,收藏9次。在SpringBoot中为了降低耦合度,简化开发,有很多方便的注解,其中@COnfigurationProperties和@ConditionalOnProperties就只个人觉得比较好用的组件中的两个@ConfigurationProperties的用法这个注解可以根据配置文件中的配置绑定相关属性到有这个注解的类上其中有四个静态方法 @AliasFor("prefix") Stri..._configurationonproperties

Visio标注、批注位置_visio标注总跑到图形中心-程序员宅基地

文章浏览阅读2.6k次。标注、批注_visio标注总跑到图形中心

随便推点

DAY8 Python入门-程序员宅基地

文章浏览阅读232次。方法没有重载在其他语言中,可以定义多个重名的方法,只要保证方法签名唯一即可。方法签名包含三个部分:方法名、参数数量、参数类型。Python中,方法的参数没有类型(调用时确定参数类型),参数的数量也可以由可变参数控制。因此,Python方法中是没有方法重载的。定义一个方法即可有多种调用方式。相当于实现了其他语言中的方法的重载。如果我们在类体中定义了多个重名的方法,只有最后一个方法有效。建议: 不要使用重名的方法,Python中方法没有重载。class Person: def say_hi(s

理解Docker容器网络之Linux Network Namespace_veth addrgenmode-程序员宅基地

文章浏览阅读695次。点击查看原文更多精彩内容由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间。随着当前项目对Kubernetes应用的深入,我感觉之前对于容器网络的粗浅理解已经不够了,容器网络成了摆在前面的“一道坎”。继续深入理解K8s网络、容器网络已经势在必行。而这篇文章就算是一个重新开始,也是对之前浅表理解的一个补充。我还是先从Docker容器网络入手,虽然Dock_veth addrgenmode

PE文件解析-文件头与整体介绍_pe文件头作用-程序员宅基地

文章浏览阅读1w次,点赞10次,收藏48次。一、PE的基本概念 PE(Portable Execute)文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任何扩展名。 认识PE文件不是作为单一内存映射文件被装入内存是很重要的。Windows加载器(又称PE加载器)遍历PE文件并决定文件的哪一部分被映射,这种映射方式是将文件较高的偏移..._pe文件头作用

Charles(HTTP抓包工具软件)中文版_charles中文版-程序员宅基地

文章浏览阅读2.6w次,点赞3次,收藏27次。Charles安装教程1、解压文件包之后双击打开“Charles 64位_4.2.7.4.msi”开始安装2、点击“Next”3、勾选“我同意条款”,然后点击“Next”4、选择软件要安装的目录,然后点击“Next”5、点击“Install”6、点击“Finish”完成安装教程1、我们打开“Charles 汉化&授权.exe”,选择“中文注册版”,然后点击“Patch”即可。资源地址:Charles(HTTP抓包工具软件)中文版Charles使用教程1、PC抓包由于该_charles中文版

Python-课题设计系统--67288(免费领源码+开发文档)可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C++、python、数据可视化、大数据、全套文案-程序员宅基地

文章浏览阅读627次,点赞28次,收藏23次。本系统采用的数据库是Mysql,使用python语言,使用django技术进行开发。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。

Centos 7.x 源码安装Ansible参考篇_centos 安装 ansible 国内源-程序员宅基地

文章浏览阅读956次。Ansible架构图_centos 安装 ansible 国内源

推荐文章

热门文章

相关标签