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

    本文分析 Free5GC Registration request procedure 注册请求流程

1. UE 发起注册请求

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

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

    根据 NAS N1 MM 消息定义

Table 8.2.6.1.1: REGISTRATION REQUEST message content

    注册请求设置移动管理类型为 MsgTypeRegistrationRequestNAS 消息需包裹在 NGAP 消息中,包括的参数为: 

  • ExtendedProtocolDiscriminator
  • Security header type
  • Spare half octet
  • Message Type
  • ngksi
  • 5GS mobile identity 9.11.3.4
  • 5GMM capability 9.11.3.1
  • UE security capability 9.11.3.54
  • NSSAI 9.11.3.37
  • Uplink data status 9.11.3.57
registrationRequest.MobileIdentity5GS = mobileIdentity
registrationRequest.Capability5GMM = &nasType.Capability5GMM{
	Iei:   nasMessage.RegistrationRequestCapability5GMMType,
	Len:   1,
	Octet: [13]uint8{0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
}
registrationRequest.UESecurityCapability = ueSecurityCapability
registrationRequest.RequestedNSSAI = requestedNSSAI
registrationRequest.UplinkDataStatus = uplinkDataStatus

    设置的 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)

InitialUEMessage, Registration request

 2 AMF 处理注册请求

    根据 NGAPPDUPresentInitiatingMessageProcedureCodeInitialUEMessage 定位到 HandleInitialUEMessage 函数

    请求的 IE 包括:

  • id-RAN- UE-NGAP-ID
  • id-NAS-PDU
  • id-UserLocationInformation
  • id-RRCEStablishmentCause
  • id-UEContextRequest
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> := <AMF Set ID><AMF Pointer><5G-TMSI>

     GUAMI := <MCC><MNC><AMF Region ID><AMF Set ID><AMF Pointer>

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

    2.1 场景对应无 UDSF 部署情况

     无 UDSF 部署情况: 如果 UE 的  5G-GUTI (全局唯一的临时 UE 标识)包含在注册请求,且从上次注册过程服务的 AMF 已更改,新的 AMF 向旧的 AMF 调用 Namf_Communication_UEContextTransfer 服务,包括完成注册服务 NAS 消息,可以是完整性保护,也可以是接入类型,来请求 UE 的 SUPI 和 UE 上下文。旧的 AMF 即使用 5G-GUTI 和完成性保护完成注册请求 NAS 消息,或者 SUPI,以及 UE 从新 AMF 验证的指示。旧 AMF 还将每个 NF消费者(UE)的事件订阅信息传给新 AMF。

if ranUe == nil {
	ranUe = ran.NewRanUe()
	ranUe.RanUeNgapId = rANUENGAPID.Value
	Ngaplog.Debugf("New RanUe [RanUeNgapID: %d]", ranUe.RanUeNgapId)

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

		servedGuami := amfSelf.ServedGuamiList[0]

		// <5G-S-TMSI> := <AMF Set ID><AMF Pointer><5G-TMSI>
		// GUAMI := <MCC><MNC><AMF Region ID><AMF Set ID><AMF Pointer>
		// 5G-GUTI := <GUAMI><5G-TMSI>
		tmpReginID, _, _ := ngapConvert.AmfIdToNgap(servedGuami.AmfId)
		amfID := ngapConvert.AmfIdToModels(tmpReginID, fiveGSTMSI.AMFSetID.Value, fiveGSTMSI.AMFPointer.Value)

		tmsi := hex.EncodeToString(fiveGSTMSI.FiveGTMSI.Value)

		guti := servedGuami.PlmnId.Mcc + servedGuami.PlmnId.Mnc + amfID + tmsi

		// TODO: invoke Namf_Communication_UEContextTransfer if serving AMF has changed since last Registration Request procedure
		// Described in TS 23.502 4.2.2.2.2 step 4 (without UDSF deployment)

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

    HandleNAS

             -->  Dispatch  设置类型为 EVENT_GMM_MESSAGE,根据初始 ue 状态为 Deregistered

func Dispatch(ue *context.AmfUe, accessType models.AccessType, procedureCode int64, msg *nas.Message) error {

	return gmm.GmmFSM.SendEvent(ue.State[accessType], gmm.GmmMessageEvent, fsm.ArgsType{
		gmm.ArgAmfUe:         ue,
		gmm.ArgAccessType:    accessType,
		gmm.ArgNASMessage:    msg.GmmMessage,
		gmm.ArgProcedureCode: procedureCode,
	})
}

            根据 DeRegistered 函数中,事件类型为 EVENT_GMM_MESSAGE 和 gmm 类型为 MsgTypeRegistrationRequest 定位到函数HandleRegistrationRequest,如果成功状态由事务 AuthRestartEvent DeRegistered --> Authentication

    2.2 HandleRegistrationRequest 函数

    根据前提为 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()

    根据 nasType.MobileIdentity5GS 中第一个字节类型为 0x01 类型为 suci

    根据  suci(imsi) = "suci-0-${mcc}-${mnc}-${routingIndentifier}-${protectionScheme}-${homeNetworkPublicKeyIdentifier}-${schemeOutput}"

          suci   -0   -460-03     -0   -0  -0    -0000007487 

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

    根觉 NAS 消息类型为 MobileIdentity5GSTypeSuci

mobileIdentity5GSContents := registrationRequest.MobileIdentity5GS.GetMobileIdentity5GSContents()
ue.IdentityTypeUsedForRegistration = nasConvert.GetTypeOfIdentity(mobileIdentity5GSContents[0])
switch ue.IdentityTypeUsedForRegistration { // get type of identity
case nasMessage.MobileIdentity5GSTypeNoIdentity:
	logger.GmmLog.Debugf("No Identity")
case nasMessage.MobileIdentity5GSTypeSuci:
	var plmnId string
	ue.Suci, plmnId = nasConvert.SuciToString(mobileIdentity5GSContents)
	ue.PlmnId = util.PlmnIdStringToModels(plmnId)
	logger.GmmLog.Debugf("SUCI: %s", ue.Suci)
	ue.IsCleartext = true

   如果 ue 不再 amf 服务小区,则发送注册 reject  

// Check TAI
if !context.InTaiList(ue.Tai, amfSelf.SupportTaiLists) {
	gmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMTrackingAreaNotAllowed, "")
	return fmt.Errorf("Registration Reject[Tracking area not allowed]")
}

     2.2.1 如果更换 AMF的情况 

     新的 AMF 向旧的 AMF 调用 Namf_Communication_UEContextTransfer,包括完成的注册请求 NAS 消息,来请求 UE 的 SUPI 和 UE 上下文(对应步骤 4)

// 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 发起请求 Namf_Communication_UEContextTransfer /ue-contexts/{ueContextId}/transfer,旧的 AMF 处理函数为 UEContextTransfer,将事件设置为 EventUEContextTransfer,发送到待处理的 channel 中,定位到函数 HTTPUEContextTransfer,流转到函数 HandleUEContextTransferRequest

     2.2.2 HandleUEContextTransferRequest 函数

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

stateeventFromTo
DeregisteredGmmMessageEventDeregisteredDeregistered
Deregistered -> AuthenticationStartAuthEventDeregisteredAuthentication
func (fsm *FSM) SendEvent(state *State, event EventType, args ArgsType) error {
	key := eventKey{
		From:  state.Current(),
		Event: event,
	}

	if trans, ok := fsm.transitions[key]; ok {
		// exit callback
		if trans.From != trans.To {
			fsm.callbacks[trans.From](state, ExitEvent, args)
		}

		// event callback
		fsm.callbacks[trans.From](state, event, args)

		// entry callback
		if trans.From != trans.To {
			state.Set(trans.To)
			fsm.callbacks[trans.To](state, EntryEvent, args)
		}
		return nil
	} else {
		return fmt.Errorf("Unknown transition[From: %s, Event: %s]", state.Current(), event)
	}
}

    根据 SendEvent 函数中,状态转移,由  Deregistered -> Authentication,From -> To(Deregistered, Authenticaion),进入 Authentication 

 

3 Authentication 函数

func Authentication(state *fsm.State, event fsm.EventType, args fsm.ArgsType) {
	logger.GmmLog.Debugln("UE in GMM State [Authentication]")

	switch event {
	case fsm.EntryEvent:
		fallthrough
	case AuthRestartEvent:
		amfUe := args[ArgAmfUe].(*context.AmfUe)
		accessType := args[ArgAccessType].(models.AccessType)

		pass, err := AuthenticationProcedure(amfUe, accessType)
		if err != nil {
			logger.GmmLog.Errorln(err)
		}
		if pass {
			if err := GmmFSM.SendEvent(state, AuthSuccessEvent, fsm.ArgsType{
				ArgAmfUe:      amfUe,
				ArgAccessType: accessType,
			}); err != nil {
				logger.GmmLog.Errorln(err)
			}
		}

 

   3.1 AuthenticationProcedure 函数

     如果发起的请求中未包含 SUCI/SUPI,则发起 TS 23.502 步骤6

func AuthenticationProcedure(ue *context.AmfUe, accessType models.AccessType) (bool, error) {
	logger.GmmLog.Info("Authentication procedure")

	// Check whether UE has SUCI and SUPI
	if IdentityVerification(ue) {
		logger.GmmLog.Debugln("UE has SUCI / SUPI")
		if ue.SecurityContextIsValid() {
			logger.GmmLog.Debugln("UE has a valid security context - skip the authentication procedure")
			return true, nil
		}
	} else {
		// Request UE's SUCI by sending identity request
		gmm_message.SendIdentityRequest(ue.RanUe[accessType], nasMessage.MobileIdentity5GSTypeSuci)
		return false, nil
	}

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

    AMF 向 AUSF 发起认证请求

AMF->AUSF的 ue-authentications request

      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}

AUSF->AMF的 ue-authentications response

   3.2 SendAuthenticationRequest 函数

     BuildAuthenticationRequest 函数创建到 UE 的 gmm 消息,BuildDownlinkNasTransport 函数构造 NGAP 消息

     STCP 协议连接发送到 RAN

     T3560 启动定时器,超过六妙将重发 SendDownlinkNasTransport,超过4次将关闭定时器

    3.3 UE 向 AMF 应答 Authentication 

     NAS 消息类型为 MsgTypeAuthenticationResponse,发送上行数据 NGAP 包裹 NSA 响应消息,类型为 NGAPPDUPresentInitiatingMessage,InitiatingMessage 类型为 ProcedureCodeUplinkNASTransportInitiatingMessagePresentUplinkNASTransport,包括的 IE 有:

    -  AMF UE NGAP ID,

    -  RAN UE NGAP ID,

    -  NAS-PDU,

    -  User Location Information

 

    3.4 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-XX-XX-0-0-0-00007487/5g-aka-confirmation

     根据返回的数据结果为 AUTHENTICATION_SUCCESS,则状态转移

stateeventFromTo
Deregistered -> AuthenticationStartAuthEventDeregisteredAuthentication
AuthenticationAuthSuccessEventAuthenticationSecurityMode
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)
	return GmmFSM.SendEvent(ue.State[accessType], AuthSuccessEvent, fsm.ArgsType{
		ArgAmfUe:      ue,
		ArgAccessType: accessType,
		ArgEAPSuccess: false,
		ArgEAPMessage: "",
	})

   3.5 SecurityMode 函数

func SecurityMode(state *fsm.State, event fsm.EventType, args fsm.ArgsType) {
	logger.GmmLog.Debugln("UE in GMM State[SecurityMode]")

	switch event {
	case fsm.EntryEvent:
		amfUe := args[ArgAmfUe].(*context.AmfUe)
		accessType := args[ArgAccessType].(models.AccessType)
		if amfUe.SecurityContextIsValid() {

		} else {
			eapSuccess := args[ArgEAPSuccess].(bool)
			eapMessage := args[ArgEAPMessage].(string)
			// Select enc/int algorithm based on ue security capability & amf's policy,
			amfSelf := context.AMF_Self()
			amfUe.SelectSecurityAlg(amfSelf.SecurityAlgorithm.IntegrityOrder, amfSelf.SecurityAlgorithm.CipheringOrder)
			// Generate KnasEnc, KnasInt
			amfUe.DerivateAlgKey()
			gmm_message.SendSecurityModeCommand(amfUe.RanUe[accessType], eapSuccess, eapMessage)
		}

        SendSecurityModeCommand 函数发送安全模式命令,NAS 消息中 MM 类型为 MsgTypeSecurityModeCommand,SendDownlinkNasTransport 函数建立 NGAP 消息包裹 NAS 消息,类型为 NGAPPDUPresentInitiatingMessageProcedureCodeDownlinkNASTransport,InitiatingMessagePresentDownlinkNASTransport 发送到 (R)AN 

DownlinkNASTransport,Security mode command

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

     NAS 消息类型为 MsgTypeSecurityModeComplete,NGAP 消息类型为 NGAPPDUPresentInitiatingMessageProcedureCodeUplinkNASTransport,InitiatingMessagePresentUplinkNASTransport

UplinkNASTransport,Security mode complete,Registration request

   3.7 AMF 处理收到的 Security mode complete

      HandleSecurityModeComplete,最后到 SendEvent 函数将状态转移,事件 SecurityModeSuccessEvent

stateeventFromTo
Deregistered -> AuthenticationStartAuthEventDeregisteredAuthentication
AuthenticationAuthSuccessEventAuthenticationSecurityMode
SecurityModeSecurityModeSuccessEventSecurityModeContextSetup
func SecurityMode(state *fsm.State, event fsm.EventType, args fsm.ArgsType) {
	logger.GmmLog.Debugln("UE in GMM State[SecurityMode]")

	switch event {

	case GmmMessageEvent:
		amfUe := args[ArgAmfUe].(*context.AmfUe)
		procedureCode := args[ArgProcedureCode].(int64)
		gmmMessage := args[ArgNASMessage].(*nas.GmmMessage)
		accessType := args[ArgAccessType].(models.AccessType)
		switch gmmMessage.GetMessageType() {
		case nas.MsgTypeSecurityModeComplete:
			if err := HandleSecurityModeComplete(amfUe, accessType, procedureCode, gmmMessage.SecurityModeComplete); err != nil {
				logger.GmmLog.Errorln(err)
			}

   3.8 HandleInitialRegistration 函数,继续以下的其他流程

func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) error {
	logger.GmmLog.Infoln("[AMF] Handle InitialRegistration")

	amfSelf := context.AMF_Self()

	// update Kgnb/Kn3iwf
	ue.UpdateSecurityContext(anType)

    3.8.1 getSubscribedNssai 函数

    SearchUdmSdmInstace 从 nrf 查找 UDM 实例,SDMGetSliceSelectionSubscriptionData 函数从 UDM 根据 plmnId查找 NSSAI 信息,包含 DefaultSingleNssais 和 SingleNssais 

func getSubscribedNssai(ue *context.AmfUe) {
			err := consumer.SearchUdmSdmInstance(ue, amfSelf.NrfUri, models.NfType_UDM, models.NfType_AMF, &param)

	problemDetails, err := consumer.SDMGetSliceSelectionSubscriptionData(ue)

}
UDM->AMF 的 nssai response

 

      3.8.2 Namf_Communication_RegistrationCompleteNotify 对应步骤 10

      如果 AMF 已经更改,新的 AMF 调用 Namf_Communication_RegistrationCompleteNotify 服务操作来通知旧的 AMF, UE 在新的 AMF 注册完成

      Namf_Communication_RegistrationCompleteNotify,/ue-contexts/{ueContextId}/transfer-update

// TODO (step 10 optional): send Namf_Communication_RegistrationCompleteNotify to old AMF if need
if ue.ServingAmfChanged {
	// If the AMF has changed the new AMF notifies the old AMF that the registration of the UE in the new AMF is completed
	req := models.UeRegStatusUpdateReqData{
		TransferStatus: models.UeContextTransferStatus_TRANSFERRED,
	}
	// TODO: based on locol policy, decide if need to change serving PCF for UE
	regStatusTransferComplete, problemDetails, err := consumer.RegistrationStatusUpdate(ue, req)
	if problemDetails != nil {
		logger.GmmLog.Errorf("Registration Status Update Failed Problem[%+v]", problemDetails)
	} else if err != nil {
		logger.GmmLog.Errorf("Registration Status Update Error[%+v]", err)
	} else {
		if regStatusTransferComplete {
			logger.GmmLog.Infof("[AMF] Registration Status Transfer complete")
		}
	}
}

      3.8.3 SendIdentityRequest 对应步骤 11

     如果 UE 未提供 PEI 也未从旧 AMF 取到 PEI,则 AMF 向 UE 发送身份请求消息以获取 PEI。

     除非 UE 执行紧急注册且无法进行身份验证,否则 PEI 应加密传输

      NAS MM 消息类型为 MsgTypeIdentityRequest

if len(ue.Pei) == 0 {
	gmm_message.SendIdentityRequest(ue.RanUe[anType], nasMessage.MobileIdentity5GSTypeImei)
	return nil
}

    3.8.4 UDM Selection 对应步骤 13

if ue.ServingAmfChanged || ue.State[models.AccessType_NON_3_GPP_ACCESS].Is(context.Registered) ||
	!ue.ContextValid {
	if err := communicateWithUDM(ue, anType); err != nil {
		return err
	}
}

      如果要执行步骤 14,基于 SUPI 的新 AMF 选择 UDM,然后 UDM 可以选择 UDR 实例,TS 23.501 [2], clause 6.3.9

      AMF 选择 UDM TS 23.501 [2], clause 6.3.8

      NRF 向 AMF 回应 UDM 信息

    3.8.5 Nudm_UECM_Registration 对应步骤 14

    如果自从上次注册程序,AMF 已经更改。新 AMF 使用 Nudm_UECM_Registration 向 UDM 注册,如果 AMF 没有 UE 的订阅数据, AMF 使用 Nudm_SDM_Get 检索 AM 订阅数据,SMF 选择订阅数据,在 SMF 中的 UE 上下文。UDM 可以通过 Nudr_DM_Query 从 UDR 检索此信息。

problemDetails, err := consumer.UeCmRegistration(ue, anType, true)
if problemDetails != nil {
	logger.GmmLog.Errorf("UECM_Registration Failed Problem[%+v]", problemDetails)
} else if err != nil {
	logger.GmmLog.Errorf("UECM_Registration Error[%+v]", err)
}

problemDetails, err = consumer.SDMGetAmData(ue)
if problemDetails != nil {
	logger.GmmLog.Errorf("SDM_Get AmData Failed Problem[%+v]", problemDetails)
} else if err != nil {
	logger.GmmLog.Errorf("SDM_Get AmData Error[%+v]", err)
}

problemDetails, err = consumer.SDMGetSmfSelectData(ue)
if problemDetails != nil {
	logger.GmmLog.Errorf("SDM_Get SmfSelectData Failed Problem[%+v]", problemDetails)
} else if err != nil {
	logger.GmmLog.Errorf("SDM_Get SmfSelectData Error[%+v]", err)
}

problemDetails, err = consumer.SDMGetUeContextInSmfData(ue)
if problemDetails != nil {
	logger.GmmLog.Errorf("SDM_Get UeContextInSmfData Failed Problem[%+v]", problemDetails)
} else if err != nil {
	logger.GmmLog.Errorf("SDM_Get UeContextInSmfData Error[%+v]", err)
}

 

    3.8.6 PCF selection

param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{
	Supi: optional.NewString(ue.Supi),
}
for {
	resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_PCF, models.NfType_AMF, &param)
	if err != nil {
		logger.GmmLog.Error("AMF can not select an PCF by NRF")
	}

   3.9 AMPolicyControlCreate (对应步骤 16)

      新的 AMF 执行一个 AM Policy Association Establishment/Modification,对于紧急注册将忽略

policyAssociationRequest := models.PolicyAssociationRequest{
	NotificationUri: amfSelf.GetIPv4Uri() + "/namf-callback/v1/am-policy/",
	Supi:            ue.Supi,
	Pei:             ue.Pei,
	Gpsi:            ue.Gpsi,
	AccessType:      anType,
	ServingPlmn: &models.NetworkId{
		Mcc: ue.PlmnId.Mcc,
		Mnc: ue.PlmnId.Mnc,
	},
	Guami: &amfSelf.ServedGuamiList[0],
}
AMF->PCF AMPolicyControlCreate request

    步骤 17,未体现:

       对于紧急请求的 UE,当注册类型为移动性注册更新,该步骤才应用 。AMF 在以下场景调用 Nsmf_PDUSession_UpdateSMContext

    3.10 步骤 18,19 UE Context Modification Request N3IWF/TNGFW-AGF

      对于非 3GPP 未支持

// TODO (step 18 optional):
// If the AMF has changed and the old AMF has indicated an existing NGAP UE association towards a N3IWF, the new AMF
// creates an NGAP UE association towards the N3IWF to which the UE is connectedsend N2 AMF mobility request to N3IWF
// if anType == models.AccessType_NON_3_GPP_ACCESS && ue.ServingAmfChanged {
// 	TODO: send N2 AMF Mobility Request
// }

    3.11 AMF 向 UE 发送 “Registration Accept”(步骤 21)

      BuildRegistrationAccept 函数,NAS 消息类型为 MsgTypeRegistrationAccept

      BuildInitialContextSetupRequest,NGAP 类型为 NGAPPDUPresentInitiatingMessage,ProcedureCodeInitialContextSetup,包括 IE 有:

    -  AMF UE NGAP ID

    -  RAN UE NGAP ID

    -  Old AMF (optional)

    -  UE Aggregate Maximum Bit Rate (conditional: if pdu session resource setup)

    -  Core Network Assistance Information (optional)

    -  GUAMI

    -  PDU Session Resource Setup Request List

    -  Allowed NSSAI

    -  UE Security Capabilities

    -  Security Key

    -  Trace Activation (optional)

    -  Mobility Restriction List (optional)

    -  UE Radio Capability (optional)

    -  Index to RAT/Frequency Selection Priority (optional)

    -  Masked IMEISV (optional)

    -  NAS-PDU (optional)

    -  RRC Inactive Transition Report Request (optional)

    -  UE Radio Capability for Paging (optional)

600

 

InitialContextSetupRequest,Registration accept

 

4. send ngap Initial Context Setup Response Msg

    NGAP 消息类型为  NGAPPDUPresentSuccessfulOutcome,ProcedureCodeInitialContextSetup

InitialContextSetupResponse

   4.1 AMF 处理 Registration Response 消息

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

	var aMFUENGAPID *ngapType.AMFUENGAPID
	var rANUENGAPID *ngapType.RANUENGAPID
	var pDUSessionResourceSetupResponseList *ngapType.PDUSessionResourceSetupListCxtRes
	var pDUSessionResourceFailedToSetupList *ngapType.PDUSessionResourceFailedToSetupListCxtRes
	var criticalityDiagnostics *ngapType.CriticalityDiagnostics

    4.1.1 如果应答消息包含 PDU 会话资源

    向 SMF 更新 SM 上下文

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, 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
		}
	}
}

 

5. send NAS Registration Complete Msg(步骤22)

    NAS 消息类型为 MsgTypeRegistrationComplete

    BuildUplinkNasTransport 函数,NGAP 消息类型为 NGAPPDUPresentInitiatingMessageProcedureCodeUplinkNASTransport,包括 IE 有:

    -  AMF UE NGAP ID

    -  RAN UE NGAP ID

    -  NAS-PDU

    -  User Location Information

UplinkNASTransport,Registration complete

   5.1 AMF 处理 HandleUplinkNasTransport

    定位到函数  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

   5.2 HandleRegistrationComplete 函数

    步骤 23 24 未实现,将状态移到 REGISTERED 状态

    状态转移

stateeventFromTo
Deregistered -> AuthenticationStartAuthEventDeregisteredAuthentication
AuthenticationAuthSuccessEventAuthenticationSecurityMode
SecurityModeSecurityModeSuccessEventSecurityModeContextSetup
ContextSetupGmmMessageEventContextSetupRegistered
func HandleRegistrationComplete(ue *context.AmfUe, accessType models.AccessType,
	registrationComplete *nasMessage.RegistrationComplete) error {

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

	util.StopT3550(ue)

	// if registrationComplete.SORTransparentContainer != nil {
	// 	TODO: if at regsitration procedure 14b, udm provide amf Steering of Roaming info & request an ack,
	// 	AMF provides the UE's ack with Nudm_SDM_Info (SOR not supportted in this stage)
	// }

	// TODO: if
	//	1. AMF has evaluated the support of IMS Voice over PS Sessions (TS 23.501 5.16.3.2)
	//	2. AMF determines that it needs to update the Homogeneous Support of IMS Voice over PS Sessions (TS 23.501 5.16.3.3)
	// Then invoke Nudm_UECM_Update to send "Homogeneous Support of IMS Voice over PS Sessions" indication to udm

	if ue.RegistrationRequest.UplinkDataStatus == nil &&
		ue.RegistrationRequest.GetFOR() == nasMessage.FollowOnRequestNoPending {
		ngap_message.SendUEContextReleaseCommand(ue.RanUe[accessType], context.UeContextN2NormalRelease,
			ngapType.CausePresentNas, ngapType.CauseNasPresentNormalRelease)
	}
	return GmmFSM.SendEvent(ue.State[accessType], ContextSetupSuccessEvent, fsm.ArgsType{
		ArgAmfUe:      ue,
		ArgAccessType: accessType,
	})
}

 

6. Registered 函数

stateeventFromTo
Deregistered -> AuthenticationStartAuthEventDeregisteredAuthentication
AuthenticationAuthSuccessEventAuthenticationSecurityMode
SecurityModeSecurityModeSuccessEventSecurityModeContextSetup
ContextSetupGmmMessageEventContextSetupRegistered
RegisteredGmmMessageEventRegisteredRegistered

 

参考:

   github, free5gc 3.0.4

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
5G核心网专业试题-169题.xls [5G核心网部署与网络规划设计]MME需要做哪些改造以支持NSA网络? 多选 支持Option3a/3X/3|5G NR的接入控制|5G NR流量计费|4/5G GW选择 [5G核心网部署与网络规划设计]关于NSA Option3/3a/3X方案话音/视频采用VoLTE/CSFB时,以下描述哪些是正确的? 多选 IMS APN固定分流到LTE基站|VoLTE手机的短信通过IMS网络处理|NR基站需开通话音功能|视频业务话务量大时容易拥塞 [5G核心网部署与网络规划设计]当NSA Option3/3a/3X话音/视频方案采用VoNR时,以下描述哪个是正确的? 多选 NR基站需开通话音功能|无NR覆盖使用VoLTE|VoNR/VoLTE手机的短信通过IMS网络处理|IMS APN优先分流到NR基站 [5G核心网部署与网络规划设计]以下关于NSA组网的描述,哪些是正确的? 多选 NSA是以现有的LTE接入和核心网作为移动性管理和覆盖的锚点,新增5G接入的组网方式|5G NR作为主站,LTE作为从站|信令面由主站处理|用户面可选择走主站或者从站 [5G核心网部署与网络规划设计]VoNR/VoeLTE相对VoLTE,IMS网络的改造点主要包括哪些? 多选 支持5G位置信息获取|支持5G接入话单|被叫域选增加对5G接入的处理|紧急呼叫支持5G小区格式 [5G核心网部署与网络规划设计]以下关于SA组网语音方案的描述中,哪些是正确的? 多选 如果不开通VoNR,打电话时由NG-RAN触发切换到4G|如果不开通VoNR,NR基站无需开通话音功能|如果开通VoNR,用户在NR覆盖下打电话就直接被NR基站处理|如果开通VoNR,不需要启用4/5G切换 [5G核心网部署与网络规划设计]以下关于USSD方案的描述,正确的有哪些? 多选 5G中,通常使用CSFB实现USSD|VoLTE部署中,USSD通常用CSFB方式实现|5G需要部署USSI AS支持UE initiated USSD|5G中,终端需要支持UE initiated USSD [5G核心网部署与网络规划设计]下列关于5G NSA组网的描述哪些是错误的? 多选 Option3a/7a都是EPC分流,好处是可以针对不同的业务进行分流,缺点是EPC不能根据无线链路状况进行分流。|Option3,7,4三种组网信令面锚定点不同,无线分别在LTE, eLTE,NR;核心网分别在EPC+,EPC+,5GC。|Option3/3a/3x组网推荐Option3,原因是不需要对现网LTE进行改造|Option4组网,适用于建网初期,LTE覆盖比较弱。 [5G核心网部署与网络规划设计]下列关于CUPS方案描述不正确的有哪些? 多选 SGW拆分成SGW-C和SGW-U,PGW拆分成PGW-C和PGW-U;MME和SGW-C融合。|CU分离后网关(GW-C+GW-U)的网元功能和外部业务接口无变化。|GW-U统一出信令接口连接周边设备,简化网络部署;|GW-C分布部署: GW-C可贴近用户,部署到城域甚至更低,缩短业务访问路径,提升用户业务体验。 [5G核心网部署与网络规划设计]5G 网络的可能的组网方案有哪些? 多选 Option7|Opiton2|Option3|Opiton4

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值