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

2023-10-13 23:10

本文主要是介绍【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.RANUENGAPIDvar nASPDU *ngapType.NASPDUvar userLocationInformation *ngapType.UserLocationInformationvar rRCEstablishmentCause *ngapType.RRCEstablishmentCausevar fiveGSTMSI *ngapType.FiveGSTMSI// var aMFSetID *ngapType.AMFSetIDvar 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.ValueNgaplog.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.GuamiamfSelf := 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 stringue.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 callbackif trans.From != trans.To {fsm.callbacks[trans.From](state, ExitEvent, args)}// event callbackfsm.callbacks[trans.From](state, event, args)// entry callbackif 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:fallthroughcase 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 SUPIif 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 requestgmm_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.AMFUENGAPIDvar rANUENGAPID *ngapType.RANUENGAPIDvar nASPDU *ngapType.NASPDUvar userLocationInformation *ngapType.UserLocationInformationif 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 = falseue.Kseaf = response.Kseafue.Supi = response.Supiue.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, KnasIntamfUe.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/Kn3iwfue.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 completedreq := models.UeRegStatusUpdateReqData{TransferStatus: models.UeContextTransferStatus_TRANSFERRED,}// TODO: based on locol policy, decide if need to change serving PCF for UEregStatusTransferComplete, 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.AMFUENGAPIDvar rANUENGAPID *ngapType.RANUENGAPIDvar pDUSessionResourceSetupResponseList *ngapType.PDUSessionResourceSetupListCxtResvar pDUSessionResourceFailedToSetupList *ngapType.PDUSessionResourceFailedToSetupListCxtResvar 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.PDUSessionResourceSetupResponseTransferresponse, _, _, 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.7if 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.AMFUENGAPIDvar rANUENGAPID *ngapType.RANUENGAPIDvar nASPDU *ngapType.NASPDUvar 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 udmif 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

这篇关于【5G核心网】free5GC 注册请求流程源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/206498

相关文章

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

Python实现NLP的完整流程介绍

《Python实现NLP的完整流程介绍》这篇文章主要为大家详细介绍了Python实现NLP的完整流程,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 编程安装和导入必要的库2. 文本数据准备3. 文本预处理3.1 小写化3.2 分词(Tokenizatio

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re