本文主要是介绍【5G核心网】free5GC 注册请求流程源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文分析 Free5GC Registration request procedure 注册请求流程
1. UE 发起注册请求
NAS Message 结构体,包括安全头部,移动管理以及会话管理消息
// Message TODO:description
type Message struct {SecurityHeader*GmmMessage*GsmMessage
}
根据 NAS N1 MM 消息定义
注册请求设置移动管理类型为 MsgTypeRegistrationRequest,NAS 消息需包裹在 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)
2 AMF 处理注册请求
根据 NGAPPDUPresentInitiatingMessage 和 ProcedureCodeInitialUEMessage 定位到 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 上下文
state | event | From | To |
Deregistered | GmmMessageEvent | Deregistered | Deregistered |
Deregistered -> Authentication | StartAuthEvent | Deregistered | Authentication |
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 发起认证请求
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.2 SendAuthenticationRequest 函数
BuildAuthenticationRequest 函数创建到 UE 的 gmm 消息,BuildDownlinkNasTransport 函数构造 NGAP 消息
STCP 协议连接发送到 RAN
T3560 启动定时器,超过六妙将重发 SendDownlinkNasTransport,超过4次将关闭定时器
3.3 UE 向 AMF 应答 Authentication
NAS 消息类型为 MsgTypeAuthenticationResponse,发送上行数据 NGAP 包裹 NSA 响应消息,类型为 NGAPPDUPresentInitiatingMessage,InitiatingMessage 类型为 ProcedureCodeUplinkNASTransport 和 InitiatingMessagePresentUplinkNASTransport,包括的 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,则状态转移
state | event | From | To |
Deregistered -> Authentication | StartAuthEvent | Deregistered | Authentication |
Authentication | AuthSuccessEvent | Authentication | SecurityMode |
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 消息,类型为 NGAPPDUPresentInitiatingMessage,ProcedureCodeDownlinkNASTransport,InitiatingMessagePresentDownlinkNASTransport 发送到 (R)AN
3.6 (R)AN 发送安全模式完成消息
NAS 消息类型为 MsgTypeSecurityModeComplete,NGAP 消息类型为 NGAPPDUPresentInitiatingMessage,ProcedureCodeUplinkNASTransport,InitiatingMessagePresentUplinkNASTransport
3.7 AMF 处理收到的 Security mode complete
HandleSecurityModeComplete,最后到 SendEvent 函数将状态转移,事件 SecurityModeSuccessEvent
state | event | From | To |
Deregistered -> Authentication | StartAuthEvent | Deregistered | Authentication |
Authentication | AuthSuccessEvent | Authentication | SecurityMode |
SecurityMode | SecurityModeSuccessEvent | SecurityMode | ContextSetup |
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, ¶m)problemDetails, err := consumer.SDMGetSliceSelectionSubscriptionData(ue)}
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, ¶m)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],
}
步骤 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)
4. send ngap Initial Context Setup Response Msg
NGAP 消息类型为 NGAPPDUPresentSuccessfulOutcome,ProcedureCodeInitialContextSetup
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 消息类型为 NGAPPDUPresentInitiatingMessage,ProcedureCodeUplinkNASTransport,包括 IE 有:
- AMF UE NGAP ID
- RAN UE NGAP ID
- NAS-PDU
- User Location Information
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 状态
状态转移
state | event | From | To |
Deregistered -> Authentication | StartAuthEvent | Deregistered | Authentication |
Authentication | AuthSuccessEvent | Authentication | SecurityMode |
SecurityMode | SecurityModeSuccessEvent | SecurityMode | ContextSetup |
ContextSetup | GmmMessageEvent | ContextSetup | Registered |
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 函数
state | event | From | To |
Deregistered -> Authentication | StartAuthEvent | Deregistered | Authentication |
Authentication | AuthSuccessEvent | Authentication | SecurityMode |
SecurityMode | SecurityModeSuccessEvent | SecurityMode | ContextSetup |
ContextSetup | GmmMessageEvent | ContextSetup | Registered |
Registered | GmmMessageEvent | Registered | Registered |
参考:
github, free5gc 3.0.4
这篇关于【5G核心网】free5GC 注册请求流程源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!