
1. 为什么IMS注册是VoLTE的第一道门槛IMS注册这件事看起来只是终端开机后自动完成的一个后台动作但如果你真正抓过包、看过信令就会发现这里面藏着不少门道。VoLTE的核心网架构里IMS是业务控制的灵魂而注册就是终端和IMS网络之间建立信任关系的第一步。没有注册成功后面所有的呼叫、保持、切换都无从谈起。1.1 注册到底在注册什么很多人以为IMS注册就是“登录一下”跟App登录没什么区别。实际上IMS注册的本质是终端向网络声明三件事我是谁、我在哪、我支持什么能力。“我是谁”靠的是IMPI和IMPU。IMPI是终端在IMS网络中的私有身份标识存在ISIM卡里相当于身份证号不会暴露给被叫方。IMPU是公有身份标识就是你的手机号码对应的SIP URI比如sip:13800138000ims.mnc001.mcc460.3gppnetwork.org这个是对外可见的。“我在哪”靠的是Contact头域终端会把自己的IP地址和端口号告诉网络。这里有个关键点VoLTE的IP地址是PGW分配的走的是专用承载和普通上网的IP不是一回事。“我支持什么能力”靠的是Feature-Tag和Accept-Contact等头域终端会告诉网络自己支持哪些编解码、哪些补充业务。注意很多注册失败的问题根源不在IMS本身而在底层承载没建好。IMS注册之前终端必须先建立默认承载和IMS信令承载这两个承载的QCI值分别是5和5优先级很高。1.2 注册流程的信令拆解完整的IMS注册流程从终端发出REGISTER开始到收到200 OK结束中间要经过P-CSCF、I-CSCF、S-CSCF三级网元。我画不了图但可以用文字把关键路径说清楚。第一步终端向P-CSCF发REGISTER消息。这条消息里带着IMPI、IMPU、Contact地址以及Security-Client头域声明自己支持的IPsec加密算法。第二步P-CSCF收到后会根据IMPI找到对应的I-CSCF地址把REGISTER转发过去。这里P-CSCF会做一件事检查终端是否已经建立了IPsec安全联盟。如果没有它会先跟终端完成IPsec协商。第三步I-CSCF收到REGISTER后会向HSS发一个UAR消息问“这个用户应该由哪个S-CSCF服务”。HSS返回UAA消息告诉I-CSCF应该选哪个S-CSCF。第四步I-CSCF把REGISTER转发给选定的S-CSCF。S-CSCF收到后向HSS发SAR消息说“我要下载这个用户的签约数据”。HSS返回SAA消息把用户签约的业务能力都传过来。第五步S-CSCF根据签约数据判断这个用户是否允许注册。如果允许它会回一个401 Unauthorized里面带着一个随机数RAND和一个认证令牌AUTN。第六步终端收到401后用ISIM卡里的密钥计算出认证响应RES然后重新发REGISTER带上Authorization头域里面包含RES。第七步S-CSCF验证RES是否正确。如果正确回200 OK注册成功。同时S-CSCF会向HSS发SAR消息更新用户注册状态。整个流程走下来正常情况下几百毫秒就完成了。但如果中间任何一个环节出问题注册就会失败。1.3 注册失败的常见坑我遇到过最多的注册失败原因排第一的是IPsec协商失败。终端和P-CSCF之间的IPsec隧道建不起来后面的信令全走不通。这种情况通常是因为终端和网络支持的加密算法不匹配或者安全联盟的参数配置有误。排第二的是HSS签约数据问题。有些用户的签约数据里没有IMS APN或者没有开通VoLTE业务S-CSCF收到SAR后直接拒绝注册。这种问题从终端侧看不出来必须查HSS的签约数据。排第三的是承载问题。IMS信令承载没建好或者QCI值配错了终端根本发不出REGISTER消息。这种情况在终端侧看就是“无服务”或者“仅限紧急呼叫”。实操心得排查注册问题时先在终端侧抓包看有没有发出REGISTER。如果发了但没收到响应问题在承载或P-CSCF。如果收到401但第二次REGISTER没发出去问题在ISIM卡或终端认证模块。如果第二次REGISTER发了但收到403问题在S-CSCF或HSS。2. IMS去注册什么时候该走什么时候不该走去注册流程经常被忽略但它其实很重要。去注册分两种终端主动发起的去注册和网络侧发起的去注册。两者的触发条件和处理方式完全不同。2.1 终端主动去注册的场景终端主动去注册通常发生在以下几种情况关机、飞行模式开启、VoLTE功能被关闭、IMS APN被断开。去注册的信令流程比注册简单很多。终端直接发一个REGISTER消息但Contact头域里的expires参数设为0。S-CSCF收到后会清除该用户的注册状态然后回200 OK。同时S-CSCF会向HSS发SAR消息把用户状态标记为未注册。这里有个细节去注册的REGISTER消息里Call-ID和CSeq要和之前注册时保持一致。如果Call-ID变了S-CSCF会认为这是一个新的注册请求而不是去注册。注意终端关机时如果来不及发去注册消息网络侧不会立即知道终端已经离线。S-CSCF会等到注册有效期超时后才清除用户状态。这个有效期通常是3600秒也就是一个小时。在这一个小时内如果有呼叫打进来网络还是会尝试寻呼终端但终端已经关机了呼叫就会失败。2.2 网络侧去注册的触发条件网络侧发起去注册通常是因为以下几种情况用户签约数据变更、S-CSCF故障倒换、管理员手动注销。网络侧去注册的信令流程是S-CSCF主动发一个NOTIFY消息给终端里面带着reginfo事件包告诉终端“你的注册状态已经变了”。终端收到后会回200 OK然后根据情况决定是否重新注册。如果是因为S-CSCF故障倒换导致的去注册终端通常会立即重新发起注册。但如果是因为签约数据变更导致的去注册终端重新注册也会被拒绝因为签约数据里已经不允许这个用户使用VoLTE了。2.3 去注册失败的排查思路去注册失败的情况比较少见但一旦出现往往会导致“幽灵注册”问题。所谓幽灵注册就是终端已经离线了但网络侧还认为终端在线导致呼叫无法正常路由。排查去注册失败首先要看终端有没有发出REGISTER消息。如果没发可能是终端侧的去注册触发条件没满足。如果发了但没收到200 OK可能是P-CSCF或S-CSCF的问题。其次要看Call-ID和CSeq是否匹配。如果Call-ID变了S-CSCF会当成新注册处理旧注册状态不会被清除。最后要看HSS的SAR消息有没有发出去。如果S-CSCF没有向HSS发SARHSS不会更新用户状态下次注册时可能会出问题。3. IMS呼叫流程从主叫拨号到被叫振铃IMS呼叫流程是VoLTE最核心的部分也是最复杂的部分。一次完整的呼叫涉及主叫侧和被叫侧的多级网元信令消息多达几十条。但如果你把流程拆开看其实逻辑很清晰。3.1 主叫侧的信令路径主叫拨号后终端首先向P-CSCF发INVITE消息。这条INVITE里带着主叫的IMPU、被叫的号码、SDP offer媒体协商信息。P-CSCF收到INVITE后会根据主叫的签约数据找到对应的S-CSCF地址把INVITE转发过去。这里P-CSCF会做一件事检查主叫是否已经注册。如果没注册直接拒绝。S-CSCF收到INVITE后会先做业务触发检查。如果主叫签约了某些补充业务比如呼叫转移、呼叫等待S-CSCF会先触发这些业务。然后S-CSCF会根据被叫号码找到被叫侧的I-CSCF地址把INVITE转发过去。被叫侧的I-CSCF收到INVITE后会向HSS发LIR消息问“这个被叫用户当前由哪个S-CSCF服务”。HSS返回LIA消息告诉I-CSCF被叫的S-CSCF地址。I-CSCF把INVITE转发给被叫的S-CSCF。被叫的S-CSCF收到后会检查被叫是否已经注册。如果被叫没注册S-CSCF会回404 Not Found主叫听到“您拨打的用户暂时无法接通”。如果被叫已经注册S-CSCF会把INVITE转发给被叫的P-CSCF然后P-CSCF再转发给被叫终端。3.2 被叫侧的振铃与应答被叫终端收到INVITE后会先回一个100 Trying告诉网络“我收到了正在处理”。然后终端会做媒体协商检查自己是否支持主叫提出的编解码格式。如果支持终端会回183 Session Progress里面带着SDP answer。同时终端开始振铃并回180 Ringing。主叫听到回铃音。被叫接听时终端回200 OK。主叫收到200 OK后回ACK确认。此时媒体通道建立双方可以通话了。这里有个关键点VoLTE的媒体通道走的是专用承载QCI1优先级最高。这个承载是在呼叫建立过程中通过PCRF动态创建的。如果PCRF没有及时创建承载就会出现“振铃了但接起来没声音”的情况。实操心得排查“接起来没声音”的问题先看专用承载有没有建起来。在终端侧看QCI1的承载是否存在如果不存在问题在PCRF或PGW。如果存在但没声音问题可能在SDP协商或编解码不匹配。3.3 呼叫流程中的关键头域IMS呼叫流程中有几个头域特别重要搞懂它们就搞懂了呼叫控制的精髓。Route头域告诉消息下一跳应该发给谁。P-CSCF、I-CSCF、S-CSCF的地址都是通过Route头域逐跳添加的。Record-Route头域告诉终端后续的请求消息比如BYE、re-INVITE应该经过哪些网元。这个头域保证了会话期间的请求消息走和INVITE相同的路径。P-Asserted-Identity头域网络侧用来传递主叫真实身份的头域。终端发的From头域里可能带的是匿名标识但P-Asserted-Identity里一定是真实号码。P-Called-Party-ID头域被叫侧用来传递被叫真实身份的头域。因为被叫可能有多个IMPU这个头域告诉终端这次呼叫是打给哪个号码的。Session-Expires头域定义会话的超时时间。如果在这个时间内没有收到re-INVITE或UPDATE消息刷新会话网络会主动释放会话。这个机制是为了防止“僵尸会话”占用资源。4. 呼叫保持流程看似简单实则暗藏玄机呼叫保持这个功能用户用起来就是按一下“保持”按钮对方听到等待音乐。但背后的信令流程涉及媒体通道的重协商、承载的修改、以及多方会话的管理。4.1 呼叫保持的信令交互主叫按“保持”按钮后终端会发一个re-INVITE消息给被叫。这个re-INVITE里带着新的SDP offer关键参数是ainactive或者asendonly。ainactive表示双方都不发媒体流asendonly表示主叫只发不收。实际网络中通常用asendonly这样主叫可以给被叫放等待音乐。被叫收到re-INVITE后回200 OK里面带着SDP answer参数是arecvonly。然后主叫回ACK媒体通道修改完成。此时被叫听到等待音乐主叫可以打第二个电话。如果主叫想恢复通话再发一个re-INVITESDP offer里参数改回asendrecv。被叫回200 OKSDP answer也是asendrecv。主叫回ACK通话恢复。4.2 呼叫保持中的承载修改呼叫保持过程中专用承载不会释放但媒体流的属性会改变。PCRF会根据SDP的变化修改承载的TFT模板把媒体流的过滤规则改成只允许等待音乐的数据包通过。这里有个容易出问题的地方如果PCRF没有及时修改承载等待音乐可能放不出来或者被叫听到的是静音。这种情况在跨厂商组网时比较常见因为不同厂商对SDP变化的处理逻辑可能不一样。注意呼叫保持期间如果主叫发起了新的呼叫网络会为主叫建立新的专用承载。此时主叫终端上会有两个QCI1的承载一个用于保持的会话一个用于新会话。如果终端不支持多承载新呼叫可能会失败。4.3 呼叫保持的常见问题最常见的问题是“保持后恢复不了”。主叫按恢复按钮但被叫还是听等待音乐。这种情况通常是re-INVITE消息丢了或者SDP协商失败。排查时先看主叫有没有发出re-INVITE。如果发了但没收到200 OK可能是被叫侧的问题。如果收到200 OK但媒体没恢复可能是承载修改没生效。第二个常见问题是“保持后等待音乐断断续续”。这通常是承载的QoS没配好等待音乐的媒体流走了默认承载而不是专用承载。默认承载的QCI9优先级低网络拥塞时会被限速。第三个常见问题是“保持后主叫听不到拨号音”。主叫想打第二个电话但拨号音出不来。这通常是因为终端没有正确管理多个会话的媒体通道导致本地音频通道被占用。5. 二次协商过程VoLTE里最容易被忽视的细节二次协商也叫re-negotiation是指在会话建立后因为某种原因需要重新协商媒体参数的过程。这个过程在VoLTE里非常常见但很多人在排查问题时容易忽略它。5.1 什么情况下会触发二次协商触发二次协商的场景很多常见的有以下几种第一种是呼叫保持和恢复。前面已经讲过保持和恢复本质上就是两次二次协商。第二种是编解码切换。比如通话过程中网络侧发现当前编解码质量不好想切换到另一个编解码。这时会发re-INVITE或UPDATE消息重新协商SDP。第三种是媒体流方向变化。比如从单向通话变成双向通话或者从语音变成视频。第四种是承载修改。比如PCRF决定修改承载的QoS参数会触发终端重新协商SDP。第五种是会话刷新。Session-Expires超时前终端会发UPDATE消息刷新会话这也算一种二次协商。5.2 二次协商的信令细节二次协商可以用re-INVITE也可以用UPDATE。两者的区别在于re-INVITE会重新走一遍完整的INVITE流程包括资源预留UPDATE只更新会话参数不重新预留资源。实际网络中呼叫保持和恢复通常用re-INVITE因为需要重新协商媒体流方向。编解码切换和会话刷新通常用UPDATE因为不需要重新预留资源。二次协商的SDP offer里终端会列出自己支持的所有编解码格式按优先级排序。被叫收到后会从里面选一个自己支持的放在SDP answer里返回。这里有个关键点SDP offer里的编解码列表必须包含当前会话正在使用的编解码。否则被叫会认为主叫不支持当前编解码可能导致会话中断。实操心得排查二次协商问题时重点看SDP offer和answer里的编解码列表是否匹配。如果offer里有AMR-WB但answer里只有AMR-NB说明被叫不支持AMR-WB网络会降级到AMR-NB。如果offer里连当前编解码都没有被叫会回488 Not Acceptable Here会话中断。5.3 二次协商失败的排查方法二次协商失败的表现通常是通话突然中断、媒体质量突然变差、或者保持后恢复不了。排查时先在终端侧抓包看有没有发出re-INVITE或UPDATE。如果没发可能是触发条件没满足。如果发了但没收到200 OK看收到的错误响应码。常见的错误响应码有488 Not Acceptable Here表示SDP协商失败500 Server Internal Error表示网络侧处理出错503 Service Unavailable表示网络侧资源不足。如果收到488重点检查SDP里的编解码列表和媒体流方向。如果收到500或503重点检查网络侧网元的状态和资源占用情况。6. 实操环境搭建与信令抓包方法前面讲了这么多理论如果不实际操作一遍很难真正理解。这一章我分享一下怎么搭建一个简易的VoLTE实验环境以及怎么抓包分析信令。6.1 实验环境的基本组成要完整复现VoLTE流程需要以下网元终端支持VoLTE的手机、eNodeB可以用小型基站、EPC包括MME、SGW、PGW、IMS包括P-CSCF、I-CSCF、S-CSCF、HSS。如果条件有限可以用开源方案搭建核心网。比如用Open5GS或者Free5GC做EPC用Kamailio或者Asterisk做IMS。终端可以用支持VoLTE的商用手机也可以用开源终端软件。注意搭建实验环境时要确保各网元之间的接口配置正确。特别是IMS和EPC之间的接口Gm接口、ISC接口、Cx接口的地址和端口必须匹配。很多实验环境搭不起来都是因为接口配置错了。6.2 信令抓包的关键位置抓包是分析VoLTE问题最有效的手段。关键抓包位置有三个第一个是终端侧。如果终端支持抓包可以直接在终端上抓。如果不支持可以在终端和eNodeB之间加一个抓包设备。第二个是P-CSCF侧。P-CSCF是IMS的信令入口在这里抓包可以看到终端和IMS之间的所有信令交互。第三个是S-CSCF侧。S-CSCF是IMS的业务控制中心在这里抓包可以看到业务触发和路由决策的过程。抓包时要注意SIP信令通常走UDP 5060端口但VoLTE的SIP信令走的是IPsec加密通道端口是动态分配的。如果抓不到明文SIP需要在P-CSCF侧配置解密。6.3 信令分析的基本方法抓到包后怎么分析我通常按以下步骤来第一步先看注册流程。找到REGISTER消息看有没有收到200 OK。如果没有看401消息里的认证参数然后看第二次REGISTER有没有发出去。第二步看呼叫流程。找到INVITE消息看有没有收到100 Trying、183 Session Progress、180 Ringing、200 OK。如果中间断了看断在哪一步。第三步看二次协商。找到re-INVITE或UPDATE消息看SDP offer和answer是否匹配。如果不匹配看错误响应码。第四步看去注册。找到expires0的REGISTER消息看有没有收到200 OK。实操心得分析信令时建议用Wireshark的SIP流程图功能。它可以把一次会话的所有信令消息按时间顺序画出来非常直观。另外Wireshark的SIP统计功能也很好用可以看到注册成功率、呼叫成功率等指标。7. 常见问题速查与避坑指南这一章我把VoLTE实操中常见的问题整理成速查表方便大家快速定位。问题现象可能原因排查方法解决思路注册失败收不到200 OKIPsec协商失败检查Security-Client和Security-Server头域确认加密算法匹配检查证书配置注册失败收到403HSS签约数据问题查HSS的IMS签约数据开通VoLTE业务添加IMS APN注册失败收不到401承载未建立检查QCI5的承载是否存在检查PGW和PCRF配置呼叫失败收到404被叫未注册查被叫的注册状态确认被叫已注册检查HSS状态振铃后接起来没声音专用承载未建立检查QCI1的承载是否存在检查PCRF和PGW的承载创建流程保持后恢复不了re-INVITE丢失或SDP协商失败抓包看re-INVITE和200 OK检查SDP编解码列表和媒体流方向保持后等待音乐断断续续承载QoS问题检查等待音乐走的承载确保等待音乐走QCI1的专用承载二次协商失败收到488SDP协商失败检查offer和answer的编解码列表确保offer包含当前编解码二次协商失败收到503网络侧资源不足检查S-CSCF和PCRF的资源占用扩容或优化资源分配去注册失败幽灵注册Call-ID不匹配检查去注册的Call-ID确保Call-ID和注册时一致除了速查表我再分享几个避坑技巧第一个技巧注册前先确认承载。IMS注册依赖QCI5的承载如果这个承载没建好注册肯定失败。在终端侧看“IMS APN”是否已连接如果没连接先排查APN配置。第二个技巧抓包时注意IPsec加密。VoLTE的SIP信令默认走IPsec加密抓到的包可能是密文。如果要在P-CSCF侧抓明文需要配置解密策略。第三个技巧关注SDP里的artpmap和afmtp。这两个属性定义了编解码的详细参数比如采样率、打包时长。如果这些参数不匹配媒体流可能无法正常传输。第四个技巧呼叫保持时注意多会话管理。如果主叫在保持一个会话的同时发起新呼叫终端需要同时管理两个会话的媒体通道。如果终端不支持新呼叫可能失败。第五个技巧二次协商时注意Session-Expires。如果Session-Expires超时前没有刷新会话网络会主动释放会话。建议在超时前一半的时间就发UPDATE刷新。8. 从信令层面理解VoLTE的业务连续性VoLTE的业务连续性说白了就是“打电话的时候走到没信号的地方电话不能断”。这个功能在IMS里叫SRVCC需要IMS和CS网络配合完成。8.1 SRVCC的基本原理SRVCC的核心思想是当终端从LTE覆盖区移动到2G/3G覆盖区时网络先把语音承载从LTE切换到CS网络然后再把IMS会话转移到CS网络。具体流程是eNodeB发现终端信号变弱向MME发切换请求。MME判断目标小区不支持VoLTE触发SRVCC流程。MME向MSC Server发SRVCC切换请求MSC Server准备好CS侧的资源后通知IMS侧做会话转移。IMS侧把会话从S-CSCF转移到MSC Server然后MME执行切换。整个流程走下来用户基本感知不到中断但信令交互非常复杂涉及EPC、IMS、CS三个域。8.2 SRVCC中的关键接口SRVCC涉及几个关键接口Sv接口连接MME和MSC Server用于传递切换请求S6a接口连接MME和HSS用于获取用户签约数据Gm接口连接终端和P-CSCF用于IMS会话控制。这些接口的配置必须一致否则SRVCC切换会失败。特别是Sv接口如果MME和MSC Server的地址不匹配切换请求发不过去。8.3 SRVCC的常见问题最常见的问题是“切换后单通”。主叫能听到被叫但被叫听不到主叫。这通常是CS侧的媒体通道没建好或者IMS侧的会话转移没完成。排查时先看MME有没有发出SRVCC切换请求。如果发了但没收到响应检查Sv接口。如果收到响应但媒体不通检查CS侧的承载和IMS侧的会话状态。第二个常见问题是“切换后掉话”。这通常是切换过程中信令超时或者目标小区资源不足。排查时看切换请求和响应的时间差如果超过阈值说明切换太慢。第三个常见问题是“切换后无法切换回来”。终端从2G/3G回到LTE时需要做反向SRVCC。如果反向SRVCC没配置终端回到LTE后无法使用VoLTE只能继续用CS网络。实操心得SRVCC的问题排查建议先在实验室环境复现。因为现网环境太复杂变量太多很难定位。实验室环境可以控制变量逐步排查。另外SRVCC的日志要开全特别是MME和MSC Server的日志关键信令消息都要记录。9. 我个人在实际操作中的体会搞VoLTE这几年踩过的坑比走过的路还多。最大的体会是VoLTE的问题80%不在IMS本身而在底层承载和配置。很多人一遇到注册失败或呼叫失败就一头扎进IMS信令里结果查了半天发现是承载没建好。第二个体会是抓包是王道。不管问题多复杂只要抓到完整的信令包总能找到线索。我习惯在排查任何问题之前先抓包先看信令流程走到哪一步断了。这比盲目查配置高效得多。第三个体会是二次协商和呼叫保持这些“高级”功能其实比基础呼叫更容易出问题。因为涉及媒体重协商和承载修改任何一个环节没处理好都会导致用户体验下降。建议在实验室环境把这些流程反复跑跑熟了再上现网。第四个体会是SRVCC这种跨域功能一定要在实验室验证充分。现网环境太复杂一旦出问题影响面很大。实验室环境可以模拟各种边界条件把问题提前暴露出来。最后分享一个小技巧如果你在排查VoLTE问题建议先看终端的QCI承载状态。QCI5的承载用于IMS信令QCI1的承载用于语音媒体。这两个承载只要有一个没建好VoLTE就用不了。在终端侧看承载状态比抓包更快能快速缩小排查范围。