【5G NR】RRC Reject解析

【5G NR】RRC Reject解析RRCReject 消息用于拒绝 RRC 连接建立或 RRC 连接重建 信令无线承载 SRB0 传输模式 TM 逻辑信道 CCCH 方向网络到 UERRCReject 消息 RRCRejectRej 用于为计时器 T302 提供以秒为单位的值 取值范围 1 16 RejectWaitTi 信息内容

1. RRC Reject描述

2. UE接收RRCReject处理流程

当UE收到RRC Reject后,按如下流程处理:

  1. 停止计时器T300,T319,T302
  2. 重置MAC并释放默认的MAC Cell Group配置;
  3. 如果在RRCReject中配置了waitTime,则启动定时器T302,将定时器值设置为waitTime;
  4. 如果收到的RRCReject是为了响应上层的请求,通知上层访问受限;
  5. 如果收到的RRCReject是用来回复RRCSetupRequest,通知上层RRC连接失败,程序结束;
    在这里插入图片描述

  6. 如果收到RRCReject是用来响应RRCResumeRequest:
    在这里插入图片描述

  • 如果上层触发resume,告知上层RRC连接失败;
  • 如果由于RNA更新而触发恢复,将变量pendingRnaUpdate设置为true,丢弃当前的KgNB密钥,KRRCenc密钥,KRRCint密钥,KUPint密钥和根据5.3.13.3导出的KUPenc密钥;
  • 暂停SRB1,程序结束;

当定时器T302运行时,RRC_INACTIVE状态的UE将继续监视寻呼。

3. 消息定义

RRCReject消息用于拒绝RRC连接建立或RRC连接重建。


RRCReject 消息

-- ASN1START -- TAG-RRCREJECT-START RRCReject ::= SEQUENCE { 
     criticalExtensions CHOICE { 
     rrcReject RRCReject-IEs, criticalExtensionsFuture SEQUENCE { 
    } } } RRCReject-IEs ::= SEQUENCE { 
     waitTime RejectWaitTime OPTIONAL, -- Need N lateNonCriticalExtension OCTET STRING OPTIONAL, nonCriticalExtension SEQUENCE{ 
    } OPTIONAL } -- TAG-RRCREJECT-STOP -- ASN1STOP 

RejectWaitTime用于为计时器T302提供以秒为单位的值,取值范围1~16。


RejectWaitTime信息内容

-- ASN1START -- TAG-REJECTWAITTIME-START RejectWaitTime ::= INTEGER (1..16) -- TAG-REJECTWAITTIME-STOP -- ASN1STOP 

4. OAI RRC Reject发送判断

在开源OAI代码中,基站收到rrcSetupRequest后,会对其携带的UE Identity类型进行判断,如果既不是随机值也不是TMSI,则会向UE发送RRC Reject。

if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { 
     ...... } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { 
     ...... } else { 
     rrc_gNB_generate_RRCReject(ctxt_pP, rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), CC_id); } 

5. OAI RRC Reject编码

熟悉ASN用法的都清楚,option选项比较多,为了适配灵活多变的数据结构,需要大量在结构体中使用指针。在实际赋值前,需要使用malloc或者calloc给指针变量申请内存。RRC Reject承载于CCCH信道,因此编码时外层需要进行DL_CCCH编码。

uint8_t do_RRCReject(uint8_t Mod_id, uint8_t *const buffer) { 
     asn_enc_rval_t enc_rval;; NR_DL_CCCH_Message_t dl_ccch_msg; NR_RRCReject_t *rrcReject; NR_RejectWaitTime_t waitTime = 1; memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t)); dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1; //指定逻辑信道消息类型为CCCH dl_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_CCCH_MessageType__c1)); dl_ccch_msg.message.choice.c1->present = NR_RRCReject__criticalExtensions_PR_rrcReject; //指定dl_ccch消息类型为rrcReject dl_ccch_msg.message.choice.c1->choice.rrcReject = CALLOC(1,sizeof(NR_RRCReject_t)); rrcReject = dl_ccch_msg.message.choice.c1->choice.rrcReject; rrcReject->criticalExtensions.choice.rrcReject = CALLOC(1, sizeof(struct NR_RRCReject_IEs)); rrcReject->criticalExtensions.choice.rrcReject->waitTime = CALLOC(1, sizeof(NR_RejectWaitTime_t)); //为waitTime申请内存 rrcReject->criticalExtensions.present = NR_RRCReject__criticalExtensions_PR_rrcReject; //设置rrcReject内部present为rrcReject rrcReject->criticalExtensions.choice.rrcReject->waitTime = &waitTime; //waitTime赋值 if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { 
     xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg); } //消息体进行per编码 enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_CCCH_Message, NULL, (void *)&dl_ccch_msg, buffer, 100); if(enc_rval.encoded == -1) { 
     LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); return -1; } LOG_D(NR_RRC,"RRCReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227866.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:21
下一篇 2026年3月16日 下午8:21


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号