【5G核心网】free5GC AMF源码分析

free5gc AMF 源码分析

1. AMF 程序初始化以及启动

   1.1 启动 httpcallback 服务

     httpcallback.AddService(router),实现在 afm/httpcallback 中,URL 以及 handler 如下所示:

Name

Pattern

HandlerFunc

Index
/
Index
SmContextStatusNotify
/smContextStatus/:guti/:pduSessionId
SmContextStatusNotify
AmPolicyControlUpdateNotifyUpdate
/am-policy/:polAssoId/update
AmPolicyControlUpdateNotifyUpdate
AmPolicyControlUpdateNotifyTerminate
/am-policy/:polAssoId/terminate
AmPolicyControlUpdateNotifyTerminate
N1MessageNotify
/n1-message-notify
N1MessageNotify

    1.2 根据配置文件中的服务列表启动服务

       serviceNameList: - namf-comm - namf-evts - namf-mt - namf-loc - namf-oam

for _, serviceName := range factory.AmfConfig.Configuration.ServiceNameList {
	switch models.ServiceName(serviceName) {
	case models.ServiceName_NAMF_COMM:
		communication.AddService(router)
	case models.ServiceName_NAMF_EVTS:
		eventexposure.AddService(router)
	case models.ServiceName_NAMF_MT:
		mt.AddService(router)
	case models.ServiceName_NAMF_LOC:
		location.AddService(router)
	}
}

    1.3 初始化 amf 上下文

     通过配置文件,较简单,amf 监听端口为 29518

	self := context.AMF_Self()
	util.InitAmfContext(self)

	addr := fmt.Sprintf("%s:%d", self.HttpIPv4Address, self.HttpIpv4Port)

    1.4 根据 ngap IP 列表建立 SCTP 服务

      TCP是以字节为单位传输的,SCTP是以数据块为单位传输的

      TCP通常是单路径传输,SCTP可以多路径传输

	for _, ngapAddr := range self.NgapIpList {
		sctpListener = sctp.Server(ngapAddr)
	}

     1.5 核心处理流程

      实现在 amf/handler/hander.go

go handler.Handle()

    1.6 注册到 NRF

      amf id 组成 regionId: 16bits, setId: 10bits, ptrId: 6bits     =

      调用 NRF Nnrf_NFManagement,注册

// Register to NRF
profile, err := consumer.BuildNFInstance(self)
if err != nil {
	initLog.Error("Build AMF Profile Error")
}

_, self.NfId, _ = consumer.SendRegisterNFInstance(self.NrfUri, self.NfId, profile)

 

2. RAN 发起的 NGSetupRequest 消息

     NG Setup 流程用来交换 NG-RAN 节点和 AMF 在 NG-C 接口上正确互操作所需的应用程序数据,该程序应是 TNL 关联开始运行后触发的第一个 NGAP 程序。该过程使用 非UE 相关的信令。

    2.1 NGAP 结构体

type NGAPPDU struct {
	Present             int
	InitiatingMessage   *InitiatingMessage
	SuccessfulOutcome   *SuccessfulOutcome
	UnsuccessfulOutcome *UnsuccessfulOutcome
}

    Present 设置为 NGAPPDUPresentInitiatingMessage

    2.2 InitiatingMessage 结构体

type InitiatingMessage struct {
	ProcedureCode ProcedureCode
	Criticality   Criticality
	Value         InitiatingMessageValue `aper:"openType,referenceFieldName:ProcedureCode"`
}

    initiatingMessage ProcedureCode 设置为 ProcedureCodeNGSetup  InitiatingMessagePresentNGSetupRequest

    当使用 NG-RAN 时,N2 参数包括所选的 PLMN ID、位置信息和与 Ue 所在小区相关的身份、Ue 上下文请求,该请求指明需要在 NG-RAN 中设置一个包含安全信息的 Ue 上下文 。也包括建立的原因,
    如果可用的话,才提供请求的 NSSAI 映射
    如果 UE 注册类型指明是定期注册更新,则省略 4 - 19 步骤
    如果 UE 包含首选的网络行为

    2.3 AMF 接收 NGSetupRequest 消息

      根据 NGAPPDUPresentInitiatingMessage 和 ProcedureCodeNGSetup 定位到 HandleNGSetupRequest

func HandleNGSetupRequest(ran *context.AmfRan, message *ngapType.NGAPPDU) {
	var globalRANNodeID *ngapType.GlobalRANNodeID
	var rANNodeName *ngapType.RANNodeName
	var supportedTAList *ngapType.SupportedTAList
	var pagingDRX *ngapType.PagingDRX

	var cause ngapType.Cause

    主要是验证信息,如果验证通过则 SendNGSetupResponse,失败则调用 SendNGSetupFailure

    如果成功则发送 NGAPPDUPresentSuccessfulOutcome,类型为 SuccessfulOutcomePresentNGSetupResponse,包括 IE:AMFName,ServedGUAMIList,relativeAMFCapacity,pLMNSupportList

 

3. RAN 发起注册请求

    Message 结构体,包括安全头部,移动管理以及会话管理消息

// Message TODO:description
type Message struct {
	SecurityHeader
	*GmmMessage
	*GsmMessage
}

    注册请求设置移动管理类型为 MsgTypeRegistrationRequest,NAS 消息需包裹在 NGAP 消息中,设置的 NGAP 消息 Present 为 NGAPPDUPresentInitiatingMessage,初始消息 ProcedureCode 为 ProcedureCodeInitialUEMessage,包括一些 IE 信息 RAN UE NGAP ID,NAS-PDU,User Location Information,RRC Establishment Cause,5G-S-TSMI (optional),AMF Set ID (optional), UE Context Request (optional), Allowed NSSAI (optional)

   3.1 AMF 处理注册请求

    根据 NGAPPDUPresentInitiatingMessage 和 ProcedureCodeInitialUEMessage 定位到 HandleInitialUEMessage 函数

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

     <5G-S-TMSI> := <5G-TMSI>

     GUAMI :=

     5G-GUTI := <5G-TMSI>

    进入核心函数 nas.HandleNAS  处理的类型为 ProcedureCodeInitialUEMessage

    3.2 HandleRegistrationRequest 函数

    根据前提为 3GPP,函数在 register_event_3gpp,根据 EVENT_GMM_MESSAGE 和 MsgTypeRegistrationRequest 定位到 HandleRegistrationRequest 函数

func HandleRegistrationRequest(ue *context.AmfUe, anType models.AccessType, procedureCode int64, registrationRequest *nasMessage.RegistrationRequest) error {

	logger.GmmLog.Info("[AMF] Handle Registration Request")

	util.ClearT3513(ue)
	util.ClearT3565(ue)

	var guamiFromUeGuti models.Guami
	amfSelf := context.AMF_Self()

    如果 NAS 消息为 RegistrationType5GSInitialRegistration 则传输设置为 “INIT_REG”

    SearchAmfCommunicationInstance 查找 AMF 实例,

    3.2.1 如果更换 AMF的情况 

     新的 AMF 向旧的 AMF 调用 Namf_Communication_UEContextTransfer,包括完成的注册请求 NAS 消息,来请求 UE 的 SUPI 和 UE 上下文

// TODO (TS 23.502 4.2.2.2 step 4): if UE's 5g-GUTI is included & serving AMF has changed since last registration procedure,
// new AMF may invoke Namf_Communication_UEContextTransfer to old AMF, including the complete registration request nas
// msg, to request UE's SUPI & UE Context
if ue.ServingAmfChanged {

    向旧的 AMF 发起请求 /ue-contexts/{ueContextId}/transfer,旧的 AMF 处理函数为 UEContextTransfer,将时间设置为 EventUEContextTransfer,发送到待处理的 channel 中,定位到函数 HandleUEContextTransferRequest

    3.2.2 HandleUEContextTransferRequest 函数

     根据消息中的 imsi / imei / 5g-guti,查找是否存在该 UE,如果存在则根据传输原因 “INIT_REG” 或者 “MOBI_REG”,如果是 “INIT_REG” 则发送 UE 上下文,包括 SUPI;如果是 “MOBI_REG”,看代码也是一样的 UE 上下文

    3.3 HandleInitialRegistration 函数

      根据注册请求的类型 定位到 HandleInitialRegistration 函数,UE 的 SUPI 和 SUCI 不能同时为空 

func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) error {

	amfSelf := context.AMF_Self()
	// Common Registration procedure
	if ue == nil {
		return fmt.Errorf("AmfUe is nil")
	}

	if ue.Supi == "" && len(ue.Suci) == 0 {
		gmm_message.SendIdentityRequest(ue.RanUe[anType], nasMessage.MobileIdentity5GSTypeSuci)
		return nil
	}

	if !ue.SecurityContextIsValid() {
		return startAuthenticationProcedure(ue, anType)
	}
	// update Kgnb/Kn3iwf
	ue.UpdateSecurityContext(anType)

     3.3.1 startAuthenticationProcedure 函数

     向 NRF 发送服务发现 AUSF 功能,向 AUSF 发送认证 Nausf_UEAuthentication,包括 Guami,UE 的 SUCI,向 AUSF 发送 POST 请求 /ue-authentications

func startAuthenticationProcedure(ue *context.AmfUe, anType models.AccessType) error {

	logger.GmmLog.Info("Start authentication procedure")

	amfSelf := context.AMF_Self()
	// TODO: consider ausf group id, Routing ID part of SUCI
	param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{}
	resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_AUSF, models.NfType_AMF, ¶m)
	if err != nil {
		logger.GmmLog.Error("AMF can not select an AUSF by NRF")
		return err
	}

     AUSF 处理的请求:

Location:[https://ausf:29509/nausf-auth/v1/ue-authentications/suci-0-208-93-0-0-0-00007487]] 201 {5G_AKA {391894b3403ae1a7e712067772fdd9a0 eff8a686c72075259d2ab857e788cb11 cc62613e215e8000a8125d9fbd1b18c9} map[link:{https://ausf:29509/nausf-auth/v1/ue-authentications/suci-0-208-93-0-0-0-00007487/5g-aka-confirmation}] 5G:mnc093.mcc208.3gppnetwork.org}

    3.3.1.1 SendAuthenticationRequest 函数

    根据 UE 的信息调用 BuildAuthenticationRequest 函数创建 NAS 消息,类型为 MsgTypeAuthenticationRequest

    3.3.1.2 SendDownlinkNasTransport 函数

    发送下行 NAS 消息,BuildDownlinkNasTransport 函数创建 NGAP 消息,将 NAS 包裹,类型为 NGAPPDUPresentInitiatingMessage,ProcedureCode 为 ProcedureCodeDownlinkNASTransport,InitiatingMessage 类型为 InitiatingMessagePresentDownlinkNASTransport,包括 的 IE:AMF UE NGAP ID,RAN UE NGAP ID,NAS PDU,Old AMF (optional),RAN Paging Priority (optional),Mobility Restriction List (optional),Index to RAT/Frequency Selection Priority (optional),UE Aggregate Maximum Bit Rate (optional),Allowed NSSAI (optional)

     STCP 协议连接发送到 RAN

     3.3.1.3 RAN 向 AMF 发送 Authentication 响应

    NAS 消息类型为 MsgTypeAuthenticationResponse,发送上行数据 NGAP 包裹 NSA 响应消息,类型为 NGAPPDUPresentInitiatingMessage,InitiatingMessage 类型为 ProcedureCodeUplinkNASTransportInitiatingMessagePresentUplinkNASTransport,包括的 IE 有:AMF UE NGAP ID,RAN UE NGAP ID,NAS-PDU,User Location Information

     3.3.2.1 AMF 处理 Authentication Response 消息

     根据 NGAPPDUPresentInitiatingMessage 和 ProcedureCodeUplinkNASTransport 定位到 HandleUplinkNasTransport 函数

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

	var aMFUENGAPID *ngapType.AMFUENGAPID
	var rANUENGAPID *ngapType.RANUENGAPID
	var nASPDU *ngapType.NASPDU
	var userLocationInformation *ngapType.UserLocationInformation

	if ran == nil {
		logger.NgapLog.Error("ran is nil")
		return
	}

     核心处理函数 HandleNAS,根据 3GPP 事件,消息设置为 EVENT_GMM_MESSAGE,AUTHENTICATION 函数中定位到 MsgTypeAuthenticationResponse 函数

func HandleAuthenticationResponse(ue *context.AmfUe, anType models.AccessType, authenticationResponse *nasMessage.AuthenticationResponse) error {

	logger.GmmLog.Info("[AMF] Handle Authentication Response")

	util.ClearT3560(ue)

    SendAuth5gAkaConfirmRequest 由 AMF 向 AUSF 调用 Nausf_UEAuthentication,/ue-authentications/{authCtxId}/5g-aka-confirmation,由 AUSF 返回 AMF 数据

200 {AUTHENTICATION_SUCCESS imsi-2089300007487 ad15bdad357c72e4d11d9dfb67d84a5a308e594740bef031e4fdf64cecdeeb01}}
[GIN] 2020/07/14 - 07:53:29 | 200 |   46.750921ms |    10.200.200.3 | PUT      /nausf-auth/v1/ue-authentications/suci-0-208-93-0-0-0-00007487/5g-aka-confirmation

     根据返回的数据结果为 AUTHENTICATION_SUCCESS

switch response.AuthResult {
case models.AuthResult_SUCCESS:
	ue.UnauthenticatedSupi = false
	ue.Kseaf = response.Kseaf
	ue.Supi = response.Supi
	ue.DerivateKamf()
	logger.GmmLog.Debugln("ue.DerivateKamf()", ue.Kamf)
	gmm_message.SendSecurityModeCommand(ue.RanUe[anType], false, "")
	return ue.Sm[anType].Transfer(state.SECURITY_MODE, nil)
    SendSecurityModeCommand 函数发送安全模式命令,NAS 消息中 MM 类型为 MsgTypeSecurityModeCommand,SendDownlinkNasTransport 函数建立 NGAP 消息包裹 NAS 消息,类型为 NGAPPDUPresentInitiatingMessage,ProcedureCodeDownlinkNASTransport,InitiatingMessagePresentDownlinkNASTransport 发送到 (R)AN

     3.3.3.1 (R)AN 发送安全模式完成消息

     NAS 消息类型为 MsgTypeSecurityModeComplete,NGAP 消息类型为 NGAPPDUPresentInitiatingMessage,ProcedureCodeUplinkNASTransport,InitiatingMessagePresentUplinkNASTransport

     3.3.3.2 AMF 处理收到的, 处理函数为 SecurityMode_3gpp

      HandleSecurityModeComplete,最后到 HandleRegistrationRequest 函数

 

4. PDU 会话建立流程

   4.1 UE 发起的 PDU 会话建立请求 (RAN -> AMF) 

    GetPduSessionEstablishmentRequest 创建 NAS-PDU,填充 NAS 消息中的 SM 消息,设置 SM 头消息类型为 MsgTypePDUSessionEstablishmentRequest,SM 头格式为:

type GsmHeader struct {
	Octet [4]uint8
}

     PDUSessionEstablishmentRequest 结构体

type PDUSessionEstablishmentRequest struct {
	nasType.ExtendedProtocolDiscriminator
	nasType.PDUSessionID
	nasType.PTI
	nasType.PDUSESSIONESTABLISHMENTREQUESTMessageIdentity
	nasType.IntegrityProtectionMaximumDataRate
	*nasType.PDUSessionType
	*nasType.SSCMode
	*nasType.Capability5GSM
	*nasType.MaximumNumberOfSupportedPacketFilters
	*nasType.AlwaysonPDUSessionRequested
	*nasType.SMPDUDNRequestContainer
	*nasType.ExtendedProtocolConfigurationOptions
}

    NAS 消息中的 MM 消息头部类型为 MsgTypeULNASTransport,设置的内容 ULNASTransport,类型为 MsgTypeULNASTransport,PayloadContainerTypeN1SMInfo

    添加 DNN,SNSSAI,PayloadContainer(上面创建的 NAS 携带 SM 消息)

type ULNASTransport struct {
	nasType.ExtendedProtocolDiscriminator
	nasType.SpareHalfOctetAndSecurityHeaderType
	nasType.ULNASTRANSPORTMessageIdentity
	nasType.SpareHalfOctetAndPayloadContainerType
	nasType.PayloadContainer
	*nasType.PduSessionID2Value
	*nasType.OldPDUSessionID
	*nasType.RequestType
	*nasType.SNSSAI
	*nasType.DNN
	*nasType.AdditionalInformation
}

    4.1.1 BuildUplinkNasTransport 函数创建 NGAP 消息

    NGAP 消息了类型为 NGAPPDUPresentInitiatingMessage,数据结构体为 InitiatingMessage,ProcedureCode 设置为 ProcedureCodeUplinkNASTransport,携带 IE 有

    // AMF UE NGAP ID

       ProtocolIEIDAMFUENGAPID     UplinkNASTransportIEsPresentAMFUENGAPID

    // RAN UE NGAP ID

       ProtocolIEIDRANUENGAPID      UplinkNASTransportIEsPresentRANUENGAPID

    // NAS-PDU

        ProtocolIEIDNASPDU                 UplinkNASTransportIEsPresentNASPDU

    // User Location Information

        ProtocolIEIDUserLocationInformation      UplinkNASTransportIEsPresentUserLocationInformation

     UPLINK NAS TRANSPORT

IE/Group Name

Presence

IE type and reference

Criticality

Assigned Criticality

Message Type

M

9.3.1.1

YES

ignore

AMF UE NGAP ID

M

9.3.3.1

YES

reject

RAN UE NGAP ID

M

9.3.3.2

YES

reject

NAS-PDU

M

9.3.3.4

YES

reject

User Location Information

M

9.3.1.16

YES

ignore

   4.2 AMF 收到 RAN 发送的 NGAP UPLINK NAS TRANSPORT 消息

    根据 NGAP 消息类型为 NGAPPDUPresentInitiatingMessage,ProcedureCode 设置为 ProcedureCodeUplinkNASTransportInitiatingMessagePresentUplinkNASTransport,定位到 HandleUplinkNasTransport

    提取出 IE 包括 AMFUENGAPID RANUENGAPID NASPDU UserLocationInformation

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

	var aMFUENGAPID *ngapType.AMFUENGAPID
	var rANUENGAPID *ngapType.RANUENGAPID
	var nASPDU *ngapType.NASPDU
	var userLocationInformation *ngapType.UserLocationInformation

    根据 3GPP 接入类型,以及 MM 消息类 MsgTypeULNASTransport,定位到函数  MsgTypeULNASTransport

    提取出 PDU session ID,Snssai,DNN,requestType(ULNASTransportRequestTypeInitialRequest)设置为 RequestType_INITIAL_REQUEST

func HandleULNASTransport(ue *context.AmfUe, anType models.AccessType, procedureCode int64, ulNasTransport *nasMessage.ULNASTransport, securityHeaderType uint8) error {
	logger.GmmLog.Infoln("Handle UL NAS Transport")

	if ue.MacFailed {
		return fmt.Errorf("NAS message integrity check failed")
	}

	switch ulNasTransport.GetPayloadContainerType() {
	case nasMessage.PayloadContainerTypeN1SMInfo:

    在处理 SM 消息根据类型为 MsgTypePDUSessionEstablishmentRequest 根据初始请求设置为:RequestType_INITIAL_REQUEST

func HandlePDUSessionEstablishmentRequest(ue *context.AmfUe, anType models.AccessType, payload []byte, pduSessionID int32, requestType models.RequestType, sNssai *models.Snssai, dnn string) error {
	// TODO Request Type Emergency requset
	var pduSession models.PduSessionContext
	pduSession.PduSessionId = pduSessionID
	pduSession.AccessType = anType
	amfSelf := context.AMF_Self()
	if requestType == models.RequestType_INITIAL_REQUEST {

    如果 UE 未提供 Snssai,则根据 UE 订阅的切片信息选择,如果 DNN 未提供,选择切片默认 DNN

    如果以上情况没有,则使用 UE Allow 切片信息

if sNssai == nil {
	if ue.SmfSelectionData != nil {
		for snssai, sNssaiInfo := range ue.SmfSelectionData.SubscribedSnssaiInfos {
			var err error
			sNssai, err = util.SnssaiHexToModels(snssai)
			if err != nil {
				return err
			}
			if dnn == "" {
				for _, dnnInfo := range sNssaiInfo.DnnInfos {
					if dnnInfo.DefaultDnnIndicator {
						dnn = dnnInfo.Dnn
						break
					}
				}
			}

		}
	}
	if sNssai == nil {
		allowedNssai := ue.AllowedNssai[anType]
		if len(allowedNssai) > 0 {
			sNssai = allowedNssai[0].AllowedSnssai
		} else {
			err := fmt.Errorf("Ue[%s] doesn't have allowedNssai\n", ue.Supi)
			logger.GmmLog.Errorf(err.Error())
			return err
		}
	}

}

       4.2.1 selectSmf 函数

【5G核心网】free5GC AMF源码分析_第1张图片

    AMF 根据切片信息,DNN 等为 PDU 会话选择 SMF

    AMF->SMF:  Nnssf_NSSelection_Get 返回了网络切片 ID,AMF 根据 NSI 找到 S-NAASI 选择 SMF

     4.2.2 如果 UE 的会话上下文存在

       则调用 SendUpdateSmContextRequest 向 SMF 发送 Nsmf_PDUSession /sm-contexts/{smContextRef}/modify 请求

// Store PduSessionContext For duplicated PDU Session Id
if smContext, ok := ue.SmContextList[pduSessionID]; ok {
	ue.StoredSmContext[pduSessionID] = &context.StoredSmContext{
		SmfId:             smfID,
		SmfUri:            smfUri,
		PduSessionContext: &pduSession,
		AnType:            anType,
		Payload:           payload,
	}

    4.3 如果 UE 的会话上下文不存在

      BuildCreateSmContextRequest 创建会话上下文请求,其包括:

    - supi

    - UnauthenticatedSupi

    - pei

    - gpsi

    - pdusessionId

    - sNssai

    - DNN

    - servingNfId

    - guami

    - servingNetwork

    - requestType

    - N1Smmsg

    - Antype

    - RatType

    - [ UeLocation ] 

    - SmContextStatusUri

smContextCreateData.Supi = ue.Supi
smContextCreateData.UnauthenticatedSupi = ue.UnauthenticatedSupi
smContextCreateData.Pei = ue.Pei
smContextCreateData.Gpsi = ue.Gpsi
smContextCreateData.PduSessionId = pduSessionContext.PduSessionId
smContextCreateData.SNssai = pduSessionContext.SNssai
smContextCreateData.Dnn = pduSessionContext.Dnn
smContextCreateData.ServingNfId = context.NfId
smContextCreateData.Guami = &context.ServedGuamiList[0]
smContextCreateData.ServingNetwork = context.ServedGuamiList[0].PlmnId

      4.3.1 SendCreateSmContextRequest

      向 SMF 发送 Nsmf_PDUSession /sm-contexts 请求

     4.3.2 SMF 回复 AMF response     

 

5. N1N2MessageTransfer(SMF->AMF)步骤 11

    包裹 N1N2MessageTransfer,设置类型为 EventN1N2MessageTransfer,丢进 channel 进行处理

   HandleN1N2MessageTransferRequest 函数

    由 SMF 向 AMF 发送的 N2 信息 ngap 类型为 NgapIeType_PDU_RES_SETUP_REQ

   5.1 N1 信息类型为 NgapIeType_PDU_RES_SETUP_REQ

case models.NgapIeType_PDU_RES_SETUP_REQ:
	HttpLog.Debugln("AMF Transfer NGAP PDU Resource Setup Req from SMF")
	var nasPdu []byte
	var err error
	if n1Msg != nil {
		pduSessionId := uint8(smInfo.PduSessionId)
		nasPdu, err = gmm_message.BuildDLNASTransport(ue, nasMessage.PayloadContainerTypeN1SMInfo, n1Msg, &pduSessionId, nil, nil, 0)
		if err != nil {
			logger.HttpLog.Errorln(err.Error())
		}
	}

    5.1.1 BuildDLNASTransport 函数

    创建 NAS MM 消息,类型设置为 MsgTypeDLNASTransport

    5.1.2 AppendPDUSessionResourceSetupListSUReq 函数

    PDUSessionResourceSetupListSUReq 结构填充 PDU 会话 ID,SNSSAI,nasPDU

    5.1.3 SendPDUSessionResourceSetupRequest 函数 N2 PDU Session Request(AMF->RAN) 步骤  12

    为多个 PDU 会话和对应的 Qos 流在 Uu 和 NG-U 分配资源,来给 UE 建立相应的 DRB,这个流程使用 UE 相关的信令,由 AMF 发起 PDU SESSION RESOURCE SETUP REQUEST 消息到 NG-RAN 节点

    BuildPDUSessionResourceSetupRequest 函数实例化 NGAPPDU 对象

    Present 设置为 NGAPPDUPresentInitiatingMessage,填充的为 initiatingMessage,ProcedureCode 设置为 ProcedureCodePDUSessionResourceSetup  InitiatingMessagePresentPDUSessionResourceSetupRequest

type NGAPPDU struct {
	Present             int
	InitiatingMessage   *InitiatingMessage
	SuccessfulOutcome   *SuccessfulOutcome
	UnsuccessfulOutcome *UnsuccessfulOutcome
}

    5.1.3.1 (IE)AMF UE NGAP ID

      ProtocolIEIDAMFUENGAPID -->  PDUSessionResourceSetupRequestIEsPresentAMFUENGAPID

    5.1.3.2 (IE)RAN UE NGAP ID

     ProtocolIEIDRANUENGAPID -->  PDUSessionResourceSetupRequestIEsPresentRANUENGAPID

    5.1.3.3(IE)Ran Paging Priority (optional)

    5.1.3.4(IE)NAS-PDU (optional)

     ProtocolIEIDNASPDU -->  PDUSessionResourceSetupRequestIEsPresentNASPDU

    5.1.3.5(IE)PDU Session Resource Setup Request list

     ProtocolIEIDPDUSessionResourceSetupListSUReq -->  PDUSessionResourceSetupRequestIEsPresentPDUSessionResourceSetupListSUReq

    5.2 N2 PDU Session Response (RAN -> AMF)步骤 14    

      NGAP 消息类型为 NGAPPDUPresentSuccessfulOutcome,填充数据结构为 SuccessfulOutcome,设置为 ProcedureCodePDUSessionResourceSetup,SuccessfulOutcomePresentPDUSessionResourceSetupResponse

      AMF 收到 N2 PDU Session Response 进行处理,定位函数为 HandlePDUSessionResourceSetupResponse,包括更新到 SMF (步骤 15) Nsmf_PDUSession_UpdateSMContextRequest

 

    NRF 中注册的 AMF 信息:

{
    "_id" : ObjectId("5f1a9c2564d2e538cb1309d7"),
    "nfInstanceId" : "d5a9f0d5-a065-43cb-ad91-65a123351ee4",
    "nfType" : "AMF",
    "nfStatus" : "REGISTERED",
    "plmnList" : [
        {
            "mcc" : "208",
            "mnc" : "93" 
        } ],
    "sNssais" : [
        {
            "sst" : 1,
            "sd" : "010203" 
        },
        {
            "sst" : 1,
            "sd" : "112233" 
        } ],
    "ipv4Addresses" : [
        "amf" ],
    "amfInfo" : {
        "taiList" : [
            {
                "plmnId" : {
                    "mcc" : "208",
                    "mnc" : "93" 
                },
                "tac" : "000001" 
            } ],
        "amfSetId" : "3f8",
        "amfRegionId" : "ca",
        "guamiList" : [
            {
                "plmnId" : {
                    "mcc" : "208",
                    "mnc" : "93" 
                },
                "amfId" : "cafe00" 
            } ] 
    },
    "nfServices" : [
        {
            "ipEndPoints" : [
                {
                    "transport" : "TCP",
                    "port" : 29518,
                    "ipv4Address" : "amf" 
                } ],
            "apiPrefix" : "https://amf:29518",
            "serviceInstanceId" : "0",
            "serviceName" : "namf-comm",
            "versions" : [
                {
                    "apiVersionInUri" : "v1",
                    "apiFullVersion" : "1.0.0" 
                } ],
            "scheme" : "https",
            "nfServiceStatus" : "REGISTERED" 
        },
        {
            "versions" : [
                {
                    "apiVersionInUri" : "v1",
                    "apiFullVersion" : "1.0.0" 
                } ],
            "scheme" : "https",
            "nfServiceStatus" : "REGISTERED",
            "ipEndPoints" : [
                {
                    "ipv4Address" : "amf",
                    "transport" : "TCP",
                    "port" : 29518 
                } ],
            "apiPrefix" : "https://amf:29518",
            "serviceInstanceId" : "1",
            "serviceName" : "namf-evts" 
        },
        {
            "scheme" : "https",
            "nfServiceStatus" : "REGISTERED",
            "ipEndPoints" : [
                {
                    "ipv4Address" : "amf",
                    "transport" : "TCP",
                    "port" : 29518 
                } ],
            "apiPrefix" : "https://amf:29518",
            "serviceInstanceId" : "2",
            "serviceName" : "namf-mt",
            "versions" : [
                {
                    "apiVersionInUri" : "v1",
                    "apiFullVersion" : "1.0.0" 
                } ] 
        },
        {
            "ipEndPoints" : [
                {
                    "ipv4Address" : "amf",
                    "transport" : "TCP",
                    "port" : 29518 
                } ],
            "apiPrefix" : "https://amf:29518",
            "serviceInstanceId" : "3",
            "serviceName" : "namf-loc",
            "versions" : [
                {
                    "apiVersionInUri" : "v1",
                    "apiFullVersion" : "1.0.0" 
                } ],
            "scheme" : "https",
            "nfServiceStatus" : "REGISTERED" 
        } ] 
}
 

你可能感兴趣的:(5G)