新闻详情

新闻详情

首页 / 资讯中心 / 详情

5G SDAP协议解析:从TS 37.324-g20看QoS flow到DRB映射

发布时间:2026/9/19 22:44:01来源:尧图网络
5G SDAP协议解析:从TS 37.324-g20看QoS flow到DRB映射
简介SDAPService Data Adaptation Protocol是5G NR用户面协议栈中的关键适配层负责将QoS流映射到数据无线承载DRB。一份3GPP 37324-g20 SDAP协议规范详解文档面向5G NR协议开发、测试与科研人员系统梳理SDAP子层的架构、实体、服务与核心流程。压缩包内含1个docx文件包体大小仅242KB正文以图文和条款结合形式呈现便于快速查阅和定位标准原文。已有582人学习/下载适合需要深入理解5G用户面协议栈的中高级工程师。文档从RRC配置的SDAP子层出发详细说明SDAP实体如何在收发端构造与解析SDAP数据PDU并重点解析上行/下行QoS流到DRB映射、反射映射、QFI标记及RQI处理等关键机制同时结合规范条款梳理了UE侧SDAP实体建立、释放、数据传输以及末端标记控制PDU构造的具体步骤例如上行会按映射规则选择DRB下行则通过SDAP头中的QFI与RDI执行反射映射读者可借此理解SDAP与下层DRB之间的协同关系快速掌握相关协议流程。1. 抓 5G 数据面先从 37324-g20 看起现网 QA 同事发来一份抓包文件问为什么同一个 QoS flow 的报文既出现在 DRB1 又出现在 DRB2 里。这个问题在 4G 时代根本不存在因为 4G 的 EPS Bearer 从核心网到空口是一条路走到黑到了 5G核心网侧是 QoS flow空口侧是 DRB中间负责把两边映射关系讲清楚的就是 SDAP。而 SDAP 的规范文本恰恰就写在 3GPP TS 37.324 里g20 是它的一个修订版本号。这篇文章要解决三件事SDAP 在整个 5G 用户面协议栈里到底站在哪一层、TS 37.324-g20 的协议字段怎么读、以及当你手里只有一份抓包或一份日志时怎么用规范文本反推现网行为。新手能照着文章把协议头解析出来熟手也能在反射 QoS 和端到端映射这类细节上找到值得再抠一遍的地方。2. 37324-g20 在 5G 协议栈里的位置以及 SDAP 的职责边界2.1 为什么核心网和空口之间非要加一个 SDAP4G 的承载模型里EPS Bearer 从 SGW/PGW 一路延伸到手机空口 DRB 和核心网承载是一一对应的。到了 5G核心网侧引入了 QoS flow 这个概念一个 PDU Session 里最多可以建几百个 QoS flow但空口侧 DRB 的数量受限于 RLC 实例和逻辑信道配置通常只有个位数。一对多还是多对一必须有协议层来做翻译这就是 SDAP 出现的根本原因。从协议栈位置看SDAP 在 PDCP 之上、IP 之下只存在于用户面。控制面没有 SDAP因为控制面的信令走 SRB不需要做 QoS flow 到 DRB 的映射。SDAP 层在 NR 用户面协议栈中直接对接 PDCP一个 SDAP 实体对应一个 PDU Session而一个 PDU Session 下面可以挂多个 DRB。这个 1 对 N 的关系就是整个映射机制的基础。2.2 g20 版本修订了什么TS 37.324 的版本号序列里g20 对应的是 3GPP Release 17 中期的维护版本。协议规范每隔一段时间会做一次文字修订和错误修正g20 不属于引入全新功能的版本但它把前几个版本里容易产生歧义的描述做了收敛尤其是反射 QoS 的定时器行为和 SDAP 头格式的边界条件。提 g20 的意义在于以它作为配置依据时终端和基站的行为预期是明确的。比如 3GPP 37.324-g20 中明确了 SDAP 头的 D/C 位和 RDI 位在特定配置下的取值规则以及 QFI 为全 1 时的保留含义。如果你手里的设备日志写的规范版本是 g00 或 g10遇到同样的 SDAP PDU 时解析结果可能有细微偏差。实际工作中我一般会在抓包的同时核对一下设备上报的协议版本号避免拿旧版文本套新版设备的行为。3. 从 3GPP 协议 37324 文本里拆出 SDAP 的 PDU 格式和字段语义3.1 协议文档里必须精读的三个段落TS 37.324 正文不算长但真正在开发排错时反复要翻的不是前面的总述而是几个特定章节。第一处是 SDAP PDU 格式的定义通常出现在第 6 章附近规定 SDAP Data PDU 和 SDAP Control PDU 的结构第二处是 QoS flow 到 DRB 映射规则的描述搞清楚了才知道什么时候该查映射表、什么时候该看 RRC 重配消息第三处是反射 QoS 的触发条件。用 TS 37.324-g20 查 SDAP 头定义时常见做法是直接翻到 SDAP Data PDU 的表格说明。下面是我从协议 37324-g20 中提取的关键字段汇总字段名和位宽依据规范文本常见定义列出字段位宽取值含义D/C1 bit0 表示 Data PDU1 表示 Control PDURDI1 bitReflect QoS 指示1 表示触发射映 QoSRQI1 bitReflect QoS 请求1 表示请求对端开启反射 QoSQFI6 bitQoS Flow ID取值 0~63PDU Type4 bit仅在 Control PDU 中出现标识控制指令类型其中 QFI 的 6 bit 是关键中的关键。QFI 取值为 0~63 不代表协议允许 64 个 QoS flow实际可用数量受限于 PDU Session 建立时的配置。而 D/C 位决定了你看到的是数据面还是控制面的 SDAP PDU抓包里 90% 以上是 Data PDU。3.2 从 TS 37.324 文本提取 SDAP Data PDU 的位布局TS 37.324 的规范文本在描述 SDAP Data PDU 时通常使用表格方式逐段列出各字段的位序。拿 g20 版本来说SDAP Data PDU 头有两种形态带 RDI 和不带 RDI。不带 RDI 的头占 1 字节8 bit 分别是 D/C1 bit、RQI1 bit、QFI6 bit带 RDI 的头占 2 字节多出一个 RDI 位。以下是我从 37324-g20 中提取的 SDAP Data PDU 头结构对应的 C 语言描述用位域方式表达typedef struct __attribute__((packed)) { uint8_t DCI : 1; // D/C: 0Data PDU, 1Control PDU uint8_t RQI : 1; // RQI: 反射 QoS 请求 uint8_t QFI : 6; // QoS Flow ID } sdap_data_pdu_header_1byte; typedef struct __attribute__((packed)) { uint8_t DCI : 1; // D/C uint8_t RDI : 1; // RDI: 反射 QoS 指示 uint8_t RQI : 1; // RQI uint8_t QFI : 5; // QFI 只有 5 bit因为 RDI 占了 1 bit } sdap_data_pdu_header_2byte;注意第二个结构体里 QFI 的位宽变了这是一个很容易踩的坑。当 SDAP 头扩展到 2 字节时QFI 的位序仍然从字节的低位开始排但可表示范围因为 RDI 位被压缩到了 5 bit。协议里对这种情况有专门说明实际解析时不能写死 6 bit必须先看 RRC 配置里 SDAP 头是否带 RDI 字段再决定用哪种结构体去解。3.3 为什么 SDAP 没有重传机制读 3GPP 协议 37324 文本时有人会问为什么 SDAP 的 PDU 格式里看不到序列号。这就要从 SDAP 的定位说起了。SDAP 不做重传、不做排序、不需要 ARQ 反馈因为它的上层 IP 包即便丢了也由 TCP 或应用层去兜底而排序和重传是 PDCP 在管的事。SDAP 在发射端只有两个动作标记 QFI、决定映射到哪个 DRB在接收端则是读取 QFI、把包交到上层对应 QoS flow 的缓冲队列里。如果把 SDAP 看作一个带状态的标签打印机它的状态只在映射关系变化时更新。这意味着 SDAP 的处理时延可以做到微秒级不引入额外缓存。但到抓包分析时你就看不到 SDAP 层有类似 PDCP SN 这样的递进数字可以跟做丢包统计必须依赖 PDCP 层或者 IP 层的信息。4. 用 37324-g20 规范落地的核心映射机制以及抓包里的判定方法4.1 QoS flow 到 DRB 的映射表建在哪里SDAP 实体维护一张映射表这张表的内容来自 RRC 重配置消息里的 sdap-Config。TS 37.324 协议 37324 文本规定 SDAP 支持两种映射模式显式映射和默认映射。显式映射要求每一条 QoS flow 至少对应到一个 DRB可以是多对一但一条 DRB 可以承载多个 QoS flow默认映射则让 SDAP 在找不到明确条目时使用默认 DRB。映射关系的建立过程是gNB 在下发 RRCReconfiguration 时携带 sdap-Config里面包含 mappedQoS-FlowsToDRB 之类的字段终端收到后以此更新 SDAP 映射表。关键点是映射表在下行和上行方向是独立的。下行方向 gNB 决定哪个 QoS flow 的数据映射到哪个 DRB终端只能被动遵守上行方向终端必须按照映射表里的规则把 IP 包放到正确的 DRB 上如果找不到映射条目就丢包或使用默认 DRB。4.2 在一个真实抓包里定位 SDAP 头和映射关系要用 Wireshark 或其他工具定位 SDAP 层关键过滤条件是数据面的 GTP-U 隧道和协议类型。5G 空口侧的 SDAP 数据面帧在 Wireshark 里不会被自动解析需要手工扩展或借助 5G 相关解析插件。最常见的做法是先用 udp.port 或者 gtpu 过滤找到用户面数据再往协议栈上层翻。用 tshark 在抓包文件里找 SDAP 相关报文的典型命令如下# 过滤 GTP-U 隧道内的 5G 用户面数据 tshark -r capture.pcapng -Y gtpu -T fields -e frame.number -e ip.src -e ip.dst -e gtpu.teid # 当 SDAP 解析插件可用时直接过滤 SDAP 层 tshark -r capture.pcapng -Y sdap.qfi -T fields -e frame.number -e sdap.qfi -e sdap.dci第一条命令用于先找到 GTP-U 的 TEIDTEID 对应到 PDU Session 的某个方向第二条命令则在解析插件支持 SDAP 的时候直接按 QFI 维度做筛选。实际抓包中如果 tshark 解析不到 sdap 层先确认一下 Wireshark 版本是否支持 5G 协议再确认抓包点是否在 GTP-U 隧道解封装之后的位置。从逻辑上讲判断一个包属于哪个 QoS flow 有两种路径路径一是在空口侧看 SDAP 头的 QFI路径二是在核心网侧看 GTP-U 扩展头里的 PDU Session Container。双端对不上通常意味着 SDAP 映射表和核心网侧的 QoS flow 绑定关系不一致这种场景在切换和负载均衡时最容易出现。4.3 反射 QoS 的实际用途和触发机制37324-g20 里对反射 QoS 的描述值得单独拎出来说。反射 QoS 的作用是让终端通过观察下行包的 SDAP 头学习上行包应该走哪条 DRB。它的触发场景通常是 gNB 希望把某个下行 QoS flow 转移到新的 DRB而又不想再走一轮 RRC 重配流程。gNB 在 SDAP 头里把 RDI 位置 1终端看到之后自动建立一条从下行 QoS flow 到下行 DRB 的反向映射。反射 QoS 的坑在于定时器。协议规定终端收到 RDI 置 1 的包后启动反射映射定时器定时器超时后必须删除对应的映射条目。如果你的测试环境里发现上行包突然走了默认 DRB一种很大可能就是这个定时器已经超时。排查思路是确认 gNB 是否周期性重发带 RDI 的包否则终端学到的映射就是临时有效。下面是一段模拟反射 QoS 学习的伪代码帮助理解逻辑def process_sdap_pdu(sdap_header, drb_id): if sdap_header.dci 0: # Data PDU qfi sdap_header.qfi if sdap_header.rdi 1: # 下行方向反射映射下行 QFI 出现在下行 DRB 上 reflective_table[qfi] drb_id start_timer(qfi, reflective_timer_ms) else: # Control PDU pass这段逻辑里reflective_table 只在收到 RDI1 的下行数据时更新。从参数角度看定时器时长由 RRC 配置里的 sdap-Config 中的 reflective QoS 定时器给出不是 SDAP 协议本身写死的值。这意味着 gNB 侧配置决定终端行为排查时要先看配置再怀疑协议实现。4.4 映射表异常时先看 RRC 重配还是先看 SDAP 头当一个业务流程出现丢包或 QoS 降级拿到抓包后的第一个问题往往不是 SDAP 层怎么解析而是到底要不要查 SDAP 头。我的习惯是三层排查法先看 IP 五元组和 DSCP判断业务类型再看 GTP-U TEID 和 QFI确认核心网给这个业务分配的 QoS flow最后才看 SDAP 头确认空口侧实际走的 DRB。如果 QFI 对得上但 DSCP 对不上是核心网侧 QoS 映射的问题如果 QFI 对得上但 SDAP 头没解析出来才是终端或基站 SDAP 处理的问题。这个顺序的底层原因是SDAP 的映射表只是最终执行者决定映射的是核心网的 QoS 规则和 RRC 配置。抓包时你看到的 SDAP 头是结果而非原因。5. 一份 37324-g20 版协议文本对应到用户面组包的具体解析函数实现5.1 把 SDAP 头从以太网帧里剥出来在写解析代码之前先说 SDAP 的用户面报文在以太网环境里的承载路径。空口侧 RLC 解包后交给 PDCPPDCP 解出 SDAP PDU随后 SDAP 去掉头后把 IP 包往上送。但在有线侧抓包时你看到的是 GTP-U 封装SDAP 头在 GTP-U 的 Payload 里。所以解析函数必须知道当前抓包点是在空口侧还是 N3 接口侧否则偏移量是错的。以下是一段针对 N3 接口抓包的 SDAP 头解析函数C 语言实现入参是 GTP-U 解封装后的 IP 包int parse_sdap_header(const uint8_t *buf, size_t len, sdap_info_t *out) { if (len 1) return -1; uint8_t byte0 buf[0]; out-dci (byte0 7) 0x1; if (out-dci 0) { // Data PDU out-rqi (byte0 6) 0x1; out-qfi byte0 0x3F; // Data PDU 是否含 RDI 由 RRC 配置决定 // 默认无 RDI 时QFI 占完整 6 bit out-header_len 1; } else { // Control PDU 结构按 37324-g20 第 6 章解析 out-pdu_type (byte0 4) 0xF; out-header_len 1; } return out-header_len; }这段函数的逻辑非常简单但实际工程里要处理的边界条件不少。第一是 len 是解封装后的长度如果小于 1 字节说明包已经被截断第二是 Data PDU 的 RDI 扩展头是否存在要由外层 RRC 配置决定函数里不判断等于没做完整。更稳妥的做法是把 RDI 配置作为入参传入代码根据配置决定是否继续读第二字节。5.2 对齐 37324-g20 的版本差异做兼容不同版本字号的 TS 37.324 之间SDAP 头定义的差别主要出现在 Control PDU 的具体语法和反射 QoS 行为的措辞上。g20 之前的一些草稿版本里对 D/C 位的描述有模糊之处g20 做了收敛。如果你在一个老设备上解析出 DCI1 但 PDU Type 为保留值的包要么是设备实现没有严格遵循 g20要么是抓包点抓到了非 SDAP 数据。此时不要急着改解析代码先确认设备侧协议版本号。在实际项目里我一般会把协议版本号和 SDAP 解析器版本做绑定像下面的配置方式# sdap_parser.conf # 绑定协议版本和解析行为 protocol_version TS37.324-g20 default_header_mode 1byte rdi_supported true control_pdu_timeout_ms 5000这样在设备升级协议版本后只需更新配置文件而不用重新编译解析器。特别注意 rdi_supported 这个参数如果协议版本是 g10 而设备固件不支持 RDI 扩展头解析器要主动避开第二字节的读取否则会把 IP 头的第一个字节误当成 SDAP 头处理。5.3 解析完 QFI 之后验证它和 DSCP 的一致性拿到 QFI 后一个很有价值的验证动作是将 SDAP 头里的 QFI 和 IP 层 DSCP 对应起来确认上下行映射是否符合预期。5G 的标准做法是 gNB 根据 QoS 规则里的 QFI 到 DSCP 映射关系来标记下行包。下面是一段用 Python 做交叉验证的脚本import dpkt def check_qfi_dscp(pcap_file): with open(pcap_file, rb) as f: pcap dpkt.pcap.Reader(f) for ts, buf in pcap: eth dpkt.ethernet.Ethernet(buf) if not hasattr(eth.data, data): continue ip eth.data # 剥掉 UDP 和 GTP-U 头后取 SDAP 头 udp ip.data gtpu_payload udp.data[8:] # GTP-U 头固定 8 字节 if len(gtpu_payload) 1: continue dci (gtpu_payload[0] 7) 0x1 if dci ! 0: continue qfi gtpu_payload[0] 0x3F dscp (ip.tos 2) 0x3F if qfi_to_dscp.get(qfi) ! dscp: print(fmismatch: qfi{qfi} dscp{dscp})脚本的逻辑是遍历 pcap 包、剥到 GTP-U payload、读第一个字节解出 QFI再把 IP 头的 DSCP 拿出来对比。qfi_to_dscp 的映射字典来自核心网侧的 QoS 规则。如果大量 mismtach 出现说明 gNB 的下行标记规则和核心网策略冲突这是比 SDAP 头解析更值得上报的现网问题。6. 快速验证你的 SDAP 解析器是否贴合 TS 37.324-g20解析器写完最怕的就是自认为对遇到真实报文却全部错位。这里给一个成本很低的验证方法。从现网抓包里挑 10 到 20 个 GTP-U 承载的包手工确认它们的 SDAP 头第一个字节D/C 位为 0 的包占比应该在 95% 以上QFI 落在核心网分配的范围内且带 RDI 的包只在配置了反射 QoS 的 PDU Session 中出现。验证命令可以这样写把一个 pcap 文件里所有 SDAP 头的 QFI 出现次数统计出来和核心网侧的会话信息对比。用 tshark 搭配一段简单统计tshark -r sample.pcapng -Y gtpu -T fields -e sdap.qfi | sort | uniq -c如果在支持 SDAP 解析的环境里直接能得到按 QFI 的分布马上就能看出有没有 QFI 越界或者分布异常。若字段显示为空确认抓包点是否正确以及 Wireshark 的 5G 协议解析插件是否加载。越界情况最常见的原因不是 SDAP 解析器写错了而是抓包时上层数据不是 SDAP PDU比如直接把 GTP-U 里的 IP 包当 SDAP 解了。这时候回到上一章的偏移量检查比继续调解析器有用得多。另一个容易漏的细节是 SDAP 头是否带 RDI 的判定。先用 RRC 配置确认 PDU Session 的 SDAP 头模式如果模式是 1 字节但抓包里出现 2 字节说明要么是异常包要么是工具配置错误。解析器里加上模式校验比事后手工查报错日志节省的时间多得多。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

0x80070570错误解析:文件损坏修复与数据恢复指南 2026/9/19 23:38:10

0x80070570错误解析:文件损坏修复与数据恢复指南

1. 0x80070570 到底在报什么:先搞懂这个错误码的来龙去脉1.1 这个错误码不是“硬盘坏了”的同义词很多人一看到“文件或目录损坏且无法读取”这行字,第一反应就是硬盘要报废了,赶紧备份数据、准备换盘。先别慌。0x80070570 这个错误码在 Wind…

阅读更多 →
PS3 存档转换指南:实机↔RPCS3 双向导入,三步走通,附排错速查表 2026/9/19 23:38:10

PS3 存档转换指南:实机↔RPCS3 双向导入,三步走通,附排错速查表

PS3 存档转换指南:实机↔RPCS3 双向导入,三步走通,附排错速查表 【免费下载链接】rpcs3 PlayStation 3 emulator and debugger 项目地址: https://gitcode.com/GitHub_Trending/rp/rpcs3 你在模拟器上打到一半,想把进度带回…

阅读更多 →
Immer 生态图谱:Built with Immer 项目全览与底层能力解析 2026/9/19 23:38:10

Immer 生态图谱:Built with Immer 项目全览与底层能力解析

Immer 生态图谱:Built with Immer 项目全览与底层能力解析 【免费下载链接】immer Create the next immutable state by mutating the current one 项目地址: https://gitcode.com/gh_mirrors/im/immer 本指南以 Immer 官方文档「Built with Immer」页面为核…

阅读更多 →
Phaser 4.0 RC2 更新深度解读:渲染节点、Shader 制服与关键修复全解析 2026/9/19 23:38:10

Phaser 4.0 RC2 更新深度解读:渲染节点、Shader 制服与关键修复全解析

Phaser 4.0 RC2 更新深度解读:渲染节点、Shader 制服与关键修复全解析 【免费下载链接】phaser Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering. 项目地…

阅读更多 →
sigma value and samples size 2026/9/19 23:38:10

sigma value and samples size

BERsigma 数10−64.753410−75.199310−85.612010−95.997810−106.361310−116.706010−127.034510−137.348810−147.650610−157.9414

阅读更多 →
Agent技能设计实战:从工具到工作流的完整指南 2026/9/19 23:35:09

Agent技能设计实战:从工具到工作流的完整指南

1. agent-skills到底要解决什么问题——先厘清概念与边界过去一年我做了不少基于大模型的应用,最深的感受是:开发一个能跑通的demo不难,难的是把三五个技能塞进同一个智能体之后,系统还能稳定、可维护、不互相打架。很多朋友一开始…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞