深入浅出asterisk(三):chan_sip代码分析(下)

本文深入分析了Asterisk中处理SIP请求的流程,包括sipsock_read()函数解析SIP包并找到或创建dialog,handle_request()根据请求类型调用不同处理函数,如handle_request_invite()用于处理INVITE请求,涉及通道创建和 dial plan 执行。同时,文章提到了outbound calls的建立,挂断操作以及handle_request_bye()函数的简单介绍。

现在回过头来把焦点转移到sipsock_read()函数。所有到来的sip包都在这里开始处理,在处理sip包期间,sipsock_read需要对sip的拥有者channel上锁,sipsock_read成功则返回0,失败则返回1。它解析sip包并且找到所在的dialog,或者创建新的dialog。并且把解析好的包交给handle_request()处理。

    sipsock_read第一步接收socket数据,存到结构sip_requestdata域中。

15062    res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len);
   

解析SIP包,获取sip request method,如INVITE, BYE

15086    parse_request(&req);
   
15087    req.method = find_sip_method(req.rlPart1);
   

    随后找到对应的sip_pvt结构,或者创建新的sip_pvt结构,结构指针返回到变量p中。

15099       /* Find the active SIP dialog or create a new one */
    
15100       p = find_call(&req, &sin, req.method); /* returns p locked */
    

   在进一步操作之前,需要对p->owner上锁,这个操作会最多尝试100次直至成功。

15107       /* Go ahead and lock the owner if it has one -- we may need it */
    
15108       /* becaues this is deadlock-prone, we need to try and unlock if failed */
    
15109       if (!p->owner || !ast_channel_trylock(p->owner))
   
15110          break;   /* locking succeeded */
    

如果上锁操作失败,将会返回503 sip消息。

15127       if (req.method != SIP_ACK)
   
15128          transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */
    
15129       /* XXX We could add retry-after to make sure they come back */
    
15130       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
   
15131       return 1;
   

更深一步的解析处理操作交给handle_request()函数处理,完了之后就是释放channel的锁。

15134    if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) {
   
15135       /* Request failed */
    
15136       if (option_debug)
   
15137          ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s/n", p->callid[0] ? p->callid : "<no callid>");
   
15138    }
   
15139       
   
15140    if (p->owner && !nounlock)
   
15141       ast_channel_unlock(p->owner);
   

  

函数handle_request()视数据包的类型而处理,如果是对外出包的回应,则交给handle_response()处理,如果是一个请求包,则视请求类型(INVITE, OPTIONS, REFER, BYE, CANCEL etc)交给不同的函数处理。如果是一个INVITE包,则交给handle_request_invite()处理,在那里将会创建一个新的channel,这个通道随后会执行一个单独的通道线程。这就是一个来电呼叫。如果这个呼叫被应答,则一个桥接通道或者PBX本身会回调sip_answer()函数。而真正的媒体数据,音频或者视频,则会在RTP子系统中处理,具体见rtp.c

Outbound calls

 Outbound calls are set up by the PBX through the sip_request_call() function. After that, they are activated by sip_call().

Hanging up

 The PBX issues a hangup on both incoming and outgoing calls through the sip_hangup() function

 

<think>首先,用户的问题是关于Asteriskchan_sip模块是否支持rtcp_mux功能。我需要基于提供的引用信息来回答。 回顾引用: - 引用[1]:在sip.conf的配置示例中提到了"rtcp_mux = yes"。这表明在chan_sip的配置中,可以设置rtcp_mux选项。 - 引用[2]:讨论了Asterisk SIP支持即时通信功能,但没有直接提到rtcp_mux。 - 引用[3]:讨论了chan_sip支持IMS VoLTE和tel URI scheme,但没有提到rtcp_mux。 关键点来自引用[1],其中在sip.conf的配置中明确设置了"rtcp_mux = yes"。这暗示chan_sip模块支持rtcp_mux功能。 rtcp_mux(RTP Control Protocol Multiplexing)是一种在同一个端口上复用RTP和RTCP流的技术,以减少使用的端口数量并简化NAT遍历。 在Asterisk中,chan_sip是较旧的SIP通道驱动程序,而PJSIP是现代的替代品。用户询问的是chan_sip是否支持rtcp_mux。 从引用[1]的配置示例来看,它确实支持,因为有一个"rtcp_mux"选项设置为"yes"。这表明在chan_sip中可以通过配置来启用rtcp_mux。 因此,我的回答应该是:是的,Asteriskchan_sip模块支持rtcp_mux功能,可以通过在sip.conf配置文件中设置"rtcp_mux = yes"来启用。 现在,根据系统级指令: - 所有行内数学表达式使用$...$格式:但这个问题不涉及数学表达式,所以可能不需要。 - 独立公式使用$$...$$:同样,不适用。 - LaTeX语法正确:不涉及数学。 - 使用中文回答:是的,整个回答要用中文。 - 生成相关问题:在回答结束后,添加相关问题部分。 - 回答中引用的段落末尾自然地添加引用标识:例如,在提到引用[1]的地方添加[^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠:基于提供的引用。 回答结构: 1. 直接回答问题。 2. 解释rtcp_mux是什么。 3. 引用配置示例来支持。 4. 添加引用标识。 5. 结束回答。 6. 添加相关问题部分。 相关问题: 基于主题,生成3个相关问题: 1. 如何配置rtcp_mux在chan_sip中? 2. rtcp_mux有什么好处? 3. 在Asterisk中,chan_sip和PJSIP在rtcp_mux支持上有何不同? 最后,确保回答简洁、准确。</think>### Asterisk chan_sip 是否支持 rtcp_mux? 是的,Asteriskchan_sip模块支持rtcp_mux功能。rtcp_mux(RTP Control Protocol Multiplexing)是一种在同一个网络端口上复用RTP(Real-time Transport Protocol)和RTCP(RTP Control Protocol)流的技术,主要用于减少端口使用量、简化NAT遍历,并提升音视频传输的效率和稳定性[^1]。 在chan_sip的配置中,您可以通过在`sip.conf`配置文件中设置`rtcp_mux = yes`来启用此功能。例如,在引用[1]的配置示例中,明确包含了这一设置: ```ini [general] udpbindaddr = 0.0.0.0:5060 realm = 123.123.123.123 ; 替换为您的Asterisk服务器公共IP transport = udp,ws,wss [199] host = dynamic secret = 199 context = default type = friend encryption = yes avpf = yes force_avp = yes icesupport = yes directmedia = no disallow = all allow = opus allow = ulaw dtlsenable = yes dtlsverify = fingerprint dtlscertfile = /etc/asterisk/keys/asterisk.pem dtlscafile = /etc/asterisk/keys/ca.crt dtlssetup = actpass rtcp_mux = yes ; 启用rtcp_mux功能 ``` 这表明chan_sip支持rtcp_mux,并且您可以通过上述配置轻松启用它[^1]。 需要注意的是,chan_sipAsterisk的旧版SIP通道驱动程序,而现代替代品PJSIP(如chan_pjsip)通常提供更好的性能和兼容性。如果您在使用中遇到问题(如NAT相关挑战),建议结合其他设置如`avpf=yes`或`icesupport=yes`来优化[^1][^3]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值