简介:VONR(Voice over New Radio)作为5G语音服务的关键技术,在实际网络中常因覆盖、邻区配置等原因出现上行单通等异常。案例文档面向5G网络优化工程师与通信运维人员,完整记录了某VIP用户在通话时只能听到对方声音却无法被对方听到的单通问题,从现象呈现、信令分析到根因定位再到复测解决的全流程。资源包含1个docx文件,压缩包大小226KB,内容结构化组织问题背景、问题描述、数据分析、问题定位、解决措施与总结注意事项。案例基于大数据平台CS/PS/用户面信令,通过15:19时段丢包定位、NR小区确认、对端EPS FB回落前MR弱覆盖(RSRP约-104dBm)等线索,锁定根因为道路覆盖质差与室外信号泄漏导致邻区漏配,最终通过增加邻区关系并复测验证解决。已有144人学习阅读。读者可从中掌握VONR端到端信令分析思路、异常信令交互流程的识别方法以及高架桥等特殊场景下邻区优化的实战经验,对处理同类5G语音质量问题具有直接参考价值。
1. VONR上行单通:现象、误区和先别急着查指标
用户正在通话,对方忽然说“喂?喂?听不到你了”,但用户自己这边能清楚听到对方声音,手机信号满格,通话计时正常,挂断重拨几次甚至又恢复正常。这就是 VONR 上行单通——语音业务由 5G 网络承载,下行方向媒体面正常,但上行方向的 RTP 语音包没有到达对端。这类问题在现网语音投诉里出现频率不低,定位起来却比单纯的弱覆盖、掉话更隐蔽:无线侧指标可能全部正常,终端没有异常记录,可问题就是实实在在地影响用户体验。下面的内容会从成因分层、定位实操、案例回溯、避坑记录到筛查脚本,把整个分析定位思路讲透。适合正在做 VoNR 语音质量优化的网优工程师、核心网语音维护人员,以及刚接手 5G 语音投诉的故障处理人员。
2. 上行单通成因分层:从无线接入网到IMS媒体面的四条主线
2.1 为什么第一步不是看指标,而是分域
遇到 VONR 上行单通,我一般先做一件事:把问题拆成四个域——终端、无线接入网、承载网、核心网 IMS。因为“上行单通”是一个结果描述,不是根因描述。用户能听到对方但对方听不到用户,说明下行方向媒体面是通的,上行方向语音包要么没有产生、要么没有发送出去、要么发送了但在中间被丢弃或改写。
如果不做分域直接拉指标,很容易陷入“这里也正常、那里也正常”的泥潭。常见做法是先确认问题方向:让用户和测试终端互打,明确是不是固定某一侧听不到。如果 A 听不到 B,那问题方向锁定在 B 的上行;如果互打都能听到,说明是特定场景或特定终端问题,不是链路问题。方向判断做错了,后面所有工作都白费。
分域之后,每一条主线都有各自的检查清单。终端域检查麦克风权限、蓝牙连接、VAD 静音抑制、编码器状态;无线接入网域检查上行覆盖、PUSCH 解调质量、上行干扰、调度参数;承载网域检查传输丢包和时延抖动;核心网 IMS 域检查 SDP 协商、放音策略、媒体面转发、RTCP 统计。四个域两两组合,很多单通问题其实在无线接入网这一层就会被拦下来。
我习惯的排查顺序是:先终端、再无线、再承载、最后核心网 IMS。终端检查成本最低,回访用户、换个耳机或开个免提,如果恢复正常就是终端问题;无线和承载网是媒体面必经路径,属于高频原因;核心网 IMS 负责会话建立与媒体转发,优先级上放在无线侧之后,但绝不能跳过。
2.2 无线侧:上行覆盖受限和PUSCH干扰是头两号嫌疑
VoNR 上行方向上,语音包从用户终端通过 PUSCH 信道发给基站,基站再转发到核心网。这个路径上最典型的两个问题是上行覆盖受限和上行干扰,它们都会造成 PUSCH 解调失败、RLC 重传超时,最终表现为 RTP 包在上行方向丢失。
上行覆盖受限的判断依据,我通常看四类数据:RSRP、PHR(功率余量报告)、PUSCH 路损、上行 BLER。RSRP 过低说明用户处于弱覆盖区,此时终端发射功率可能已经顶到上限;PHR 如果很小甚至为负,说明用户功率余量为零,调度给满 MCS 等级也解调不了;上行 BLER 长期高于 10%~15%,且伴随 HARQ 重传,基本可以确认上行覆盖不可用。
上行干扰的判断依据以 PUSCH SINR 和上行 PRB 干扰噪声为主。如果覆盖正常但 PUSCH SINR 长期在低值徘徊,大概率是底噪被抬高。常见干扰源包括系统内同频干扰、系统外直放站、无源器件互调等。有一个反直觉的点:下行 RSRP 和 SINR 可能都很漂亮,但上行已经被干扰抬高了底噪。因为基站接收侧的噪声抬升不像终端侧指标那样直观,PUSCH SINR 不落到具体 RB 上很难通过路测发现。
从现网经验看,上行单通和上行丢包的关系是直接的:语音包经过 RLC 分片后映射到 PUSCH,PUSCH 解调失败后触发重传,重传一旦超过时延预算,语音包就被丢弃。一次呼叫中连续丢几十个 RTP 包,人耳就能明显感知为“听不清”或“单通”。所以无线侧排查的核心不是看某个小时均值,而是看连续劣化的时间段、对应的无线指标采样点,以及该时段 PUSCH SINR 的波动形态。
2.3 核心网侧:SDP协商、放音策略和RTCP统计是盲区
无线侧查不出明显问题的时候,很多人会把原因归给“终端玄学”,但我的习惯是先把核心网媒体面资料完整拉出来看一遍。第一个必查项是 SDP 协商结果。VoNR 一般使用 AMR-WB 编码,采样率 16kHz;如果协商成了 AMR-NB,音色变化会让人误以为声音发闷,但这不属于单通。单通要看媒体流是否存在持续单向发送,以及 RTP 端口和编解码模式是否与会话建立时的协商结果一致。
如果上行 RTP 端口与协商不一致,语音包到达 IMS 网关时会被直接丢弃,出现整段上行无声音。这种问题的隐蔽性在于:终端侧已经按协商结果发送,核心网侧却按另一个端口接收,抓包时能看到上行 RTP 包到达,但应用层一个包都没送出去。
第二个必查项是放音策略。核心网 IMS 在特定场景下会插入放音,比如用户触发了某些补充业务,或媒体面资源不可用。放音策略一旦配置错误,会把上行语音替换成提示音,体验上就是“对方听不到我,但能听到其他声音”。用户往往会把这个现象描述成“回声”或“电流声”,需要通过信令里是否有放音资源插入的指示来判断。
第三个必查项是 RTCP 统计。RTCP 与 RTP 共用媒体通道,RTCP 中的丢包率、抖动、往返时延能直接反映上行方向是否值得继续深挖。如果上行 RTCP 丢包率持续走高而无线侧指标正常,问题多半在承载网或核心网转发链路。这里有个排查工具上的坑:很多采集平台默认不解析 RTCP,只看 RTP 包完好就判定正常,实际上有一半 RTCP 都丢了——这说明链路质量已经明显劣化。
3. 端到端定位实操:四步从用户投诉压到单通点
3.1 第一步:用信令跟踪和媒体抓包给通话做“切片”
动手之前先把采集工作做完。我常用的组合是四路数据并行:核心网侧抓取 IMS 信令跟踪、媒体面做端口镜像抓包、无线侧提取用户级 MR 采样、终端侧开启 DFT 日志。这四路数据如果时间对齐,就能对一个通话做完整的“切片”。
信令跟踪负责看 SIP 会话建立流程,重点看 INVITE 的 SDP、183 Session Progress、200 OK 的媒体协商,以及 UPDATE 消息里是否有媒体端口变更。媒体抓包用来统计上下行 RTP 包的收发速率、序列号、时间戳和丢包情况。终端 DFT 日志负责定位终端侧问题,比如上行静音检测误判、编码器切换、麦克风采集异常等。
实际操作中,数据对齐是第一个坑。无线侧 MR 是周期上报的,建议取 T310 开始到呼叫释放的时长来分析;媒体面抓包围绕通话起止时间前后各扩 1 分钟;信令跟踪直接按用户号码或者 IMSI 过滤。四路数据时间差控制在秒级以内,否则很难把某个瞬时劣化和具体原因对上。时间没有对齐就开始分析,后面每一步都可能被带偏。
3.2 第二步:用语音质量KPI把问题从“面”压到“点”
数据齐了之后,不建议一上来就看最底层的采样点,而是先用语音质量 KPI 确认问题是否可复现。常用的三个指标是 MOS 估计值(如 POLQA)、RTP 丢包率、端到端时延抖动。
看 MOS 绝对值有时候会误判。MOS 3 以下明显有问题,但 MOS 3.5 以上也不代表一切正常,起伏剧烈的 MOS 曲线比一条平稳低值的曲线更有分析价值。RTP 丢包率一定要分方向统计:上行单通必然体现为上行方向丢包率偏高或长时间无包,下行方向丢包率正常,这是判断方向最直接的证据。
抖动指标重点关注两个区间:通话前 10 秒的初始抖动,以及通话过程中的抖动峰值。峰值超过 60~80ms 时,终端 Jitter Buffer 大概率溢出,表现为“一字一顿”或短暂单通。当 KPI 把问题方向确认在上行之后,再把范围压缩到具体路段和小区:拉取该时段该小区的上行 PRB 干扰噪声、PUSCH SINR、上行 BLER、PHR 和 RLC 重传率。这个步骤不需要精确到每个业务包,但能确认无线侧是否有系统性劣化窗口。
3.3 第三步:无线侧两项排查和两个常用干预参数
无线侧现场排查,我一般做两件事:第一件是看覆盖和干扰的关联关系,第二件是做一个上行调度验证。
覆盖层面,调出采样点的 TA 和 PHR 值。TA 一跳约 78 米,如果 TA 突跳明显,说明用户可能在高速移动或处于小区切换边界,上行功控跟不上会导致语音包赶不上时序;PHR 持续为 0 甚至负值,说明终端到了功率上限,此时应重点核查用户是否位于小区边缘。
干扰层面,看上行 PRB 干扰噪声均值,再按 RB 索引分布排查。如果高干扰 RB 是一段连续的,且与邻区 PCI 模三干扰的分布特征对应,基本可以锁定系统内干扰来源;如果高干扰 RB 随机分布但整体抬高,更多要考虑系统外干扰。这里有一个可操作的验证方法:在基站侧临时关闭该小区上行调度 50ms,观察底噪是否回落,同时联系现场做无源器件互调排查。高干扰不一定会导致单通,但会显著抬高上行 BLER,造成语音包丢包率飙升。
两个常用的干预参数,一个是 PUSCH 开环功控的目标接收功率(p0NominalPUSCH),现网典型配置在 -100 到 -90dBm 之间;上行弱覆盖场景适当上调 2~3dB 可以改善解调,但调过头会抬升全网底噪,动之前必须先确认干扰噪声数据没有问题。另一个是上行自适应 MCS 的下限,弱覆盖场景下把下限从 QPSK 放开到 16QAM 并不能改善覆盖,反而增加重传概率,保持 QPSK 更稳妥。
注意,参数干预只是验证手段,不是最终结论。调整完观察 15~30 分钟看 PUSCH SINR 和上行 BLER 变化,有明显改善说明根因在覆盖或干扰;没有变化就果断回滚参数,把排查重点转回核心网媒体面。
3.4 第四步:核心网媒体面与终端日志复核
无线侧找不到结论时,把 2.3 节提到的三个盲区逐项复核。SDP 协商再看一遍媒体端口、编解码列表、RTP payload 类型是否匹配;放音策略检查通话过程中是否有提示音资源被插入;RTCP 统计对照媒体面抓包的上下行包数是否对称,判断链路是否真的干净。
终端日志复核主要确认三件事:终端是否进入半双工状态、上行 DTX 是否异常频繁、语音编码是否持续发生上采样或下采样。有些终端为了省电,在长时间单方说话时会启用静音抑制,如果 VAD 检测错误,会把正常语音判定为静音而不发送上行包。这种问题在无线侧和核心网侧都看不到,只能靠终端日志确认。
如果四路数据全部正常,最后才排查承载网。媒体面走 IP 传输,中间跨 PTN/SPN 组网,传输丢包和 MTU 分片也能造成单通。核查方式是在媒体面的两个抓包点同时抓包对比,定位是哪一个传输节点丢包。这一步执行成本较高,通常放到最后,但个别案例里它就是真正的根因。
4. 案例复盘:一个上行单通是怎么从“玄学”变成“确定”的
4.1 投诉背景与数据拉取:先看统计再看单用户采样
某地市近期连续收到十几起语音投诉,现象高度一致:5G 用户拨打电话时,对方听不到用户声音,用户自己听对方声音清晰。投诉集中在上午 9~11 点,用户位置分散在同一个区域内的三个小区,无线侧初步排查未发现告警。这是典型的“数据层面无异常但用户感知异常”的上行单通场景。
我接手后先做两件事。第一件是把三个小区近一周的 VoNR 语音 KPI 拉出来,按小时聚合看上行 RTP 丢包率和上行 BLER,发现上午 9~11 点的丢包率确实高出其他时段一个数量级,但整体平均值只有 3% 上下,如果不细分时段很容易被当成正常波动。第二件是把投诉用户的呼叫记录全部提取出来,看是否存在共同特征:同一个终端型号、同一条移动轨迹、同一种通话场景。
有意思的是,十几位投诉用户里有七八位都经过了同一个路口,这让我把注意力集中到路口附近的两个小区上,而不是分散在整个片区的三个小区里。这一步的教训是:用户位置和时间的聚合分析,比逐个用户翻 MR 更高效,能把“面”快速压缩成“点”。
4.2 无线指标定位与干扰源验证
从投诉用户中拉取一条完整的 MR 采样看:RSRP 约 -95dBm,下行 SINR 约 15dB,覆盖尚可;但 PUSCH SINR 在通话过程中持续低于 -3dB,MCS 被压制在 QPSK,上行 BLER 时高时低。下行指标那么好看,上行却这么差,这是外部干扰最典型的特征。
接下来把基站侧上行 PRB 干扰噪声数据拉出来,按 RB 分布形态看,发现在某段连续 RB 上干扰噪声平均抬高了 8dB 左右。再对照天馈台账,三个小区共享同一个室内分布系统末端的某无源器件,该器件已超出设计带宽范围。进一步验证时,联系现场维护用频谱仪在馈线侧扫频,果然在目标频段看到非业务信号的带外分量。
这里也做过一次干扰源误判的反复:一开始怀疑是外部直放站,后来锁频扫测发现频谱特征与直放站不符,才回头查共享器件台账。如果早一步把台账和 RB 分布做关联,排查时间能缩短至少半天。移除该问题器件后,上行 PRB 干扰噪声回落到正常水平,PUSCH SINR 恢复到 8dB 以上。
4.3 处理结果与复盘要点
处理完成后观察一周,投诉量归零,上行 RTP 丢包率从峰值 3.2% 回落到 0.1% 以下,复测时让用户以相同路径拨打,单通不再复现。这件事给整个团队最直观的提醒是:下行指标正常不代表上行链路健康,PUSCH SINR 和上行 PRB 干扰噪声才是上行单通的第一现场。
复盘下来有三个要点值得记住。第一,PUSCH SINR 是判断上行质量最核心的指标,不要只看 RSRP;第二,干扰类型的判断可以先用 RB 分布形态猜方向,再结合硬件台账精确定位,快速压缩排查成本;第三,投诉时间与位置的聚合分析比单用户逐点分析更有价值,多个小区同一时段出现同类问题,基本可以排除终端因素,把方向锁定在公共无线环境。
5. VONR上行单通排查避坑:五个容易误判的坑
5.1 误把上行单通当下行单通排查
现象:接到投诉后按“听不到对方声音”去排查下行覆盖,调天线倾角、提升下行功率,折腾一圈问题依旧。
原因:没有先确认“谁听不到谁”。用户的描述往往是模糊的,习惯用自己的视角描述问题,排查时很容易把上行单通当成双向问题处理。
解决:第一次回访就明确测试方向。让用户与固定测试终端互打,分别记录两个方向的声音连续性。用户能听到对方、对方听不到用户,问题方向锁在上行,无线侧只看 PUSCH SINR、PHR、上行 BLER,不碰下行参数,减少无效动作。
5.2 只看平均丢包率,漏掉瞬间劣化
现象:拉取全时段 RTP 丢包率,平均值 2% 以下判定正常,但用户投诉时段内丢包连续持续了 5 秒以上,早就造成明显单通。
原因:平均值掩盖瞬时劣化。语音质量感知不是按小时平均来体验的,用户感受到的是秒级质量,任何 3~5 秒的连续丢包都有可能形成单通。
解决:按分钟或按单次通话粒度聚合丢包率,重点看连续丢包事件次数和最大持续丢包时长。丢包率 3% 以下的呼叫不代表没有瞬间劣化,连续丢包 30 个以上 RTP 包基本必然造成听感断裂。
5.3 无线指标全绿,问题出在IMS媒体面放音
现象:无线侧采样正常,覆盖良好,上行 BLER 不超标,但用户对端仍然听不到用户声音,听到的是重复提示音或杂音。
原因:核心网侧插入了放音资源,上行媒体流被替换或叠加,无线侧完全看不到核心网媒体面发生的资源变化。
解决:在 IMS 信令里查找携带媒体资源更新或放音相关指示的消息,再看 SDP 中媒体端口或 payload 类型是否发生变更。发现放音插入后,重点核查触发逻辑,比如是否误触发了呼叫保持,或媒体资源参数配置错误。
5.4 忽略VoNR和EPS FB的切换场景
现象:单通发生在通话后几十秒到几分钟之间,规律是用户从 5G 覆盖边缘道路驶过时出现。
原因:VoNR 通话切换到 EPS FB 的过程中,媒体面从 5G QoS Flow 映射到 4G 承载,如果互操作参数里的映射优先级或丢弃优先级配错,上行语音承载可能被数据业务抢占或错误释放。
解决:查看通话过程中是否发生了语音连续性切换,对比切换前后的 RTP 包收发速率。切换后上行无包,直接检查互操作策略配置和承载映射表,重点看 QCI=1 的承载在目标侧是否建立成功并保持正确优先级。
5.5 偶发单通复现困难时,不会抓包
现象:用户反馈偶发单通,到场测试时一切正常,连续拨打多轮也复现不了,最后不了了之。
原因:偶发问题只在特定无线环境、特定时间、特定网络负荷组合下出现,人工到场测试的复现概率极低。用人力反复路测,收益很低。
解决:在核心网侧对重点用户号码持续开启媒体面抓包和信令跟踪,无线侧开启用户级 MR 记录,按周期保存。下一次投诉出现时,直接通过后台原始记录做离线分析,不需要现场复现。这是把偶发问题从死角里捞出来的常用手段,前期准备的存储成本远低于现场反复测试的投入。
6. 把定位经验沉淀成筛查脚本:一个上行单通快速筛查技巧
6.1 为什么先做丢包统计而不是直接抓RTP完整解码
媒体面抓包文件动辄几百 MB,直接打开 Wireshark 逐包翻看效率很低,尤其是遇到小时段劣化,翻包会翻到怀疑人生。我的习惯是先跑一个丢包筛查脚本,从抓包里快速统计出每个语音流的丢包率、连续丢包事件和丢包发生时间点,把可疑时段圈定之后,再有针对性地看对应窗口的 RTP 包细节。
6.2 一个可直接改的Python筛查脚本
用 Wireshark 导出 RTP 字段 CSV,然后跑下面这段脚本,就能得到每个语音流的丢包情况。
import csv import sys from collections import defaultdict def load_packets(csv_path): packets = [] with open(csv_path, newline='', encoding='utf-8-sig') as f: reader = csv.DictReader(f) for row in reader: packets.append({ 'frame': row['frame.number'], 'time': float(row['frame.time_relative']), 'src': row['ip.src'], 'dst': row['ip.dst'], 'ssrc': row['rtp.ssrc'], 'seq': int(row['rtp.seq']), }) return packets def analyze_loss(packets): streams = defaultdict(list) for p in packets: streams[p['ssrc']].append(p) for ssrc, plist in streams.items(): plist.sort(key=lambda x: x['seq']) total = len(plist) lost = 0 events = 0 prev = None for pkt in plist: if prev is not None: diff = (pkt['seq'] - prev) % 65536 if diff > 1: lost += diff - 1 events += 1 print(f"SSRC={ssrc} 时间={pkt['time']:.2f}s " f"序列号 {prev}->{pkt['seq']} 丢包约{diff-1}") prev = pkt['seq'] rate = lost / (total + lost) * 100 if total + lost else 0 print(f"SSRC={ssrc} 总包={total} 丢包={lost} " f"丢包率={rate:.2f}% 连续丢包事件={events}") if rate > 0 and events > 0: print(f" -> 该流有丢包,建议优先看时间点附近的无线指标") if __name__ == '__main__': if len(sys.argv) != 2: print("用法: python rtp_loss.py rtp_export.csv") sys.exit(1) analyze_loss(load_packets(sys.argv[1]))脚本逻辑说明:按 SSRC 把同一路语音流分组,RTP 序列号是 16 位计数,范围 0~65535,所以相邻序列号差值按 65536 取模;差值大于 1 说明中间有包在链路中丢失,或数据包乱序未能被同一路会话捕获。连续丢包事件次数比丢包率更能反映瞬时劣化,事件次数越多,越有可能出现听感断裂。
参数说明:Wireshark 导出 CSV 时至少包含 frame.number、frame.time_relative、ip.src、ip.dst、rtp.ssrc、rtp.seq 六个字段。抓包里如果存在乱序包,脚本会把它计为丢包,但 VoNR 媒体面很少出现严重乱序,对排查结论影响不大。经验阈值上,丢包率超过 3% 且事件次数超过 2 次,就要跟进该时段的 PUSCH SINR 和高层指标。
6.3 两个使用技巧和一个习惯
第一个技巧:导出 CSV 前在 Wireshark 里先用 udp.port 过滤出某一通电话的媒体流,只分析单次呼叫,否则多路语音流混在一起,SSRC 分组多且耗时。第二个技巧:把脚本输出重定向到文本文件,再用时间字段与无线侧 MR 采样对齐,直接看丢包发生前后的无线环境。
我现在处理完一个上行单通案例,都会把结果归档成一份带根因结论的记录,再顺手把结论备注在脚本同目录下。时间长了之后,再遇到类似投诉,先跑脚本、再翻结论记录,基本十分钟就能判断是复用老根因还是新问题。这个习惯帮我躲过了很多次重复的低效排查,希望帮到你。
本文还有配套的精品资源,点击获取