在Vovida的基础上实现自己的SIP协议栈(六)

在Vovida的基础上实现自己的SIP协议栈(六)

卢政 2003/08/08

3.3 等待对方的呼叫:

  上面花了那么长的时间叙述了如何发起一个呼叫,我们再来介绍一下如何接收一个呼叫:

  当用户进入Idle状态以后,如果系统接收到一个INVITE消息,系统将进入Ring状态,并且进入Opring操作中,这个时候硬件设备将播放振铃声,这个时候如果用户决定摘机通话,那么offhook事件就会产生,同时OpAnswerCall将使状态机进入InCall状态,向主叫发送200响应消息,同样RTP/RTCP通道打开,开始通话,如果通话完毕,双方挂机,那么互相发送SIP Bye消息,OpEndCall将使系统重新回到Idle状态。

  下图表示了从接收到INVITE消息通话完毕的各个状态之间程序各种类之间的迁移过程,和主动呼叫的情况一样,如果协议栈软件应用于Marshal或者是Redirection Server的话,那么采用的协议流程和下面又有一些不一样了,在后续章节会对这些做详细介绍。

  在本图中粗体的部分表示加入MyEntryOperator队列中的操作符
正体的部分表示加入MyOperator队列中的操作符
斜体的部分表示加入MyExitOperator队列中的操作符


(点击放大)


下面我们来详细地介绍每个操作:

3.3.1 OpRing等待对方的振铃消息

OpRing:获取对端向本地发送的INVITE消息
const Sptr < State >
OpRing::process( const Sptr < SipProxyEvent > event )
{
Sptr < SipEvent > sipEvent;
sipEvent.dynamicCast( event );
if ( sipEvent == 0 )
{
return 0;
}
Sptr < SipMsg > sipMsg = sipEvent->getSipMsg();
assert( sipMsg != 0 );
//接收INVITE消息;
Sptr < InviteMsg > msg;
msg.dynamicCast( sipMsg );
… …

Sptr < UaCallInfo > call;
call.dynamicCast( event->getCallInfo() );
assert( call != 0 );
//在UaCallInfo中存储当前的INVITE消息;
call->setRingInvite( new InviteMsg( *msg ) );
call->setContactMsg(*msg);
//保存当前的路由消息;
call->setCalleeRoute1List( msg->getrecordrouteList() );
int numContact = msg->getNumContact();
if ( numContact )
{//保存连接
SipContact contact = msg->getContact( numContact - 1 );
Sptr < SipRoute > route = new SipRoute;
route->setUrl( contact.getUrl() );
call->addRoute1( route );
}
… …
Sptr< BaseUrl > baseUrl = msg->getFrom().getUrl();
assert( baseUrl != 0 );
// Assume we have a SIP_URL
Sptr< SipUrl > sipUrl;
sipUrl.dynamicCast( baseUrl );
assert( sipUrl != 0 );
//获取主叫的Sip URL
Data callingNum = sipUrl->getUserValue();
callingNum += "@";
callingNum += sipUrl->getHost();
signal->dataList.push_back( callingNum.getData(lo) );
//把主叫和被叫的地址(URL)都装入设备的信号队列中,为媒体流和铃声回放的RTP信道做准备
SipRequestLine reqLine = msg->getRequestLine();
baseUrl = reqLine.getUrl();
assert( baseUrl != 0 );

sipUrl.dynamicCast( baseUrl );
assert( sipUrl != 0 );
string calledNum = sipUrl->getUserValue().getData(lo);
signal->dataList.push_back( calledNum );
UaDevice::getDeviceQueue()->add( signal );
//获取主叫的SDP
Sptr remoteSdp;
remoteSdp.dynamicCast (msg->getContentData(0));
bool ringbackTone = false;
//创建本地的SDP
SipSdp localSdp;
if ( remoteSdp != 0 )
{
localSdp = *remoteSdp;
Data host = theSystem.gethostAddress();
if(UaConfiguration::instance()->getNATAddress() != "")
{
host = UaConfiguration::instance()->getNATAddress();
}
//设定本地的SDP
setStandardSdp(localSdp, host,UaDevice::instance()->getRtpPort());
}
//获取本地状态是否当前的硬件状态支持Call Waiting
HardwareStatusType hdwStatus = UaDevice::instance()->getHardwareStatus();
//检验本地是否支持零声回放(回放的话要在零声消息里增加本地的SDP)
StatusMsg statusMsg;
if (UaConfiguration::
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中的SIP协议栈是指可以通过Python程序使用SIP协议与其他SIP实体进行通信的模块。通过SIP模块,Python程序可以实现SIP User Agent或SIP Server的功能,包括发起和接收呼叫、会议邀请等操作。在Python中,有一些库可以用于开发SIP应用程序,例如PySIP和Blinker。使用这些库,我们可以使用Python编写代码来建立SIP通话。例如,使用PySIP库,可以通过以下代码段建立SIP通话: ```python import sip sip.setapi('QString', 2) sip.setapi('QVariant', 2) from PyQt4.QtGui import * from PyQt4.QtCore import * from PyQt4.QtNetwork import * from pysip import Call from pysip import SIPURI callee = SIPURI('sip:[email protected]') caller = SIPURI('sip:[email protected]') call = Call(caller, callee) call.invite() ``` 需要注意的是,SIP协议类似于Python,也采用GPL协议(包括v2和v3)。因此,如果使用SIP协议栈开发应用程序,必须遵循GPL协议的规定。SIP协议是一种被广泛应用于VoIP领域的网络通信协议,它可以用于建立、维护和结束实时会话,如语音通话、视频会议等。而Python是一种高级编程语言,可以快速、简单地开发出各种应用程序。因此,结合SIP与Python的开发,可以使用SIP模块和相应的Python库来实现各种SIP功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [使用SIP模块和相应的Python库](https://blog.csdn.net/qq_42151074/article/details/129453957)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Python - SIP参考指南 - 介绍](https://blog.csdn.net/weixin_39611174/article/details/111848525)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值