Asterisk中如何修改SIP INVITE消息?交换主叫用户名与显示名
解决Asterisk交换INVITE主叫用户名与显示名的方案
作为玩了多年Asterisk的老玩家,我给你分两种路径解决这个需求——优先推荐不用改代码的配置方案,毕竟改源码门槛高还不好维护;如果你确实需要通过代码实现,我也给你指个方向。
一、不用改代码:通过Dialplan实现(最推荐)
不管你用的是新版的PJSIP还是旧版的chan_sip,都可以在拨号计划里轻松实现主叫用户名和显示名的交换,步骤如下:
- 打开Asterisk的拨号计划配置文件
extensions.conf - 在你处理内部呼叫的上下文里(比如默认的
[from-internal]),添加这段逻辑:
exten => _XXX,1,NoOp(开始交换主叫用户名与显示名) ; 先把原始的主叫号码(用户名)和显示名存到临时变量,避免覆盖 exten => _XXX,n,Set(ORIG_CALLER_NUM=${CALLERID(num)}) exten => _XXX,n,Set(ORIG_CALLER_NAME=${CALLERID(name)}) ; 交换两者的值:把主叫号码设为原来的显示名,显示名设为原来的号码 exten => _XXX,n,Set(CALLERID(num)=${ORIG_CALLER_NAME}) exten => _XXX,n,Set(CALLERID(name)=${ORIG_CALLER_NUM}) ; 正常呼叫目标客户端 exten => _XXX,n,Dial(PJSIP/${EXTEN})
把_XXX换成你实际的分机匹配规则(比如_3XXX匹配3开头的4位分机),如果是chan_sip就把PJSIP/${EXTEN}改成SIP/${EXTEN}。
这段代码的作用是:在A呼叫B时,先把A的原始主叫用户名(比如3000)和显示名(比如666)存起来,然后交换两者的值,再发起呼叫。这样发给B的INVITE消息里,From头就会变成"3000" <sip:666@你的Asterisk服务器地址>,完美满足你的需求。
二、改代码实现(适合有开发能力的场景)
如果一定要通过修改Asterisk源码实现,那得针对你用的SIP驱动(PJSIP/chan_sip)来改,这里以主流的PJSIP为例:
- 获取Asterisk源码,进入
chan_pjsip目录 - 打开
pjsip_session.c文件,找到构建并发送INVITE请求的函数ast_pjsip_session_send_invite - 在函数里找到构建From头的部分,添加交换逻辑:
// 找到已有的From头 pjsip_from_hdr *from = pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL); if (from && from->uri && PJSIP_URI_SCHEME_IS_SIP(from->uri)) { pjsip_sip_uri *sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(from->uri); // 保存原始的用户名和显示名 pj_str_t orig_user = sip_uri->user; pj_str_t orig_display = from->display; // 交换:把显示名设为原始用户名,用户名设为原始显示名 pj_strdup2(msg->pool, &from->display, orig_user.ptr); pj_strdup2(msg->pool, &sip_uri->user, orig_display.ptr); }
- 重新编译Asterisk,安装替换原有的二进制文件
⚠️ 注意:改源码的缺点很明显——Asterisk升级时你的修改会被覆盖,而且需要具备C语言开发和编译Asterisk的能力,除非有特殊需求,否则不推荐。
内容的提问来源于stack exchange,提问作者Wu Yuan Chun
相关产品推荐
相关产品推荐

