Resiprocate介绍 下载本文

利用Resiprocate实现UA需要实现一个Sip客户服务端代理实现类来和UI等交互及完成事件回调控制。

要处理sip的一系列事件,必须继承相关事件句柄控制接口,它们都是一些抽象类,如: InviteSessionHandler 会话的事件接口 ClientRegistrationHandler 注册登陆事件接口 。。。。。。

继承这些接口,说明客户端将要响应相关事件,一般而言肯定要组册和会话,因此上面的两个事件接口是一定要继承和实现的。

因此一般来说sip客户代理类要管理和实现事件抽象接口。见相关例子。

DialogUsageManager是sip事务层管理类,是一个大总管的角色;看其Makexxx系列的函数能明白它能发起一系列登陆、会话邀请的动作及其回复。

因此这样的Sample就完成了一个会话邀请:

NameAddr uacAor; 被邀请方的Sip Uri地址

uacAor.uri().scheme() = \

uacAor.uri().user() = Data(“705147”); sip的注册帐号

uacAor.uri().host() = Data(“fwd.pulver.com”); 注册服务器的URL或者IP地址

//接下来就是一通初始化工作,应该能看明白 //set up UAC

SipStack stackUac;

DialogUsageManager* dumUac = new DialogUsageManager(stackUac); dumUac->addTransport(UDP, 12005);

SharedPtr uacMasterProfile(new MasterProfile); auto_ptr uacAuth(new ClientAuthManager); dumUac->setMasterProfile(uacMasterProfile); dumUac->setClientAuthManager(uacAuth);

TestUac uac;

16

dumUac->setInviteSessionHandler(&uac); dumUac->setClientRegistrationHandler(&uac); dumUac->addOutOfDialogHandler(OPTIONS, &uac);

auto_ptr uac_dsf(new testAppDialogSetFactory); dumUac->setAppDialogSetFactory(uac_dsf);

//your aor, credentials, etc here

dumUac->getMasterProfile()->setDigestCredential(uacAor.uri().host(), uacAor.uri().user(), uacPasswd);

dumUac->getMasterProfile()->setDefaultFrom(uacAor); dumUac->getMasterProfile()->setDefaultRegistrationTime(70);

dumUac->send(dumUac->makeInviteSession(uasAor, uac.sdp, new

testAppDialogSet(*dumUac, \如此就生成了SIP会话邀请的消息发了出去。 参考代码:BasicCall.cxx

//类似的登录注册更简单:

SipMessage& regMessage = dumUac->makeRegistration(uacAor, new testAppDialogSet(*dumUac, \dumUac->send(regMessage);

然后就交给这样的一个后台处理流程去处理吧:

unsigned long __stdcall UacThreadFunction(void* arg) {

UaAgent* uac = (UaAgent*)arg;

resip::DialogUsageManager* dumUac = uac->mDum; resip::SipStack* m_hSipStack = uac->mStack; for(;;) {

FdSet fdset;

17

m_hSipStack->buildFdSet(fdset);

int err =

fdset.selectMilliSeconds(resipMin((int)m_hSipStack->getTimeTillNextProcessMS(),10)); }

在Dum(DialogUsageManager)的类中基本上这样一条线:

DialogUsageManager产生Dialog Set,Dialog Set产生Dialog,Dialog产生

InviteSession; InviteSession又分Client InviteSession和Server InviteSession。

Dum部门还定义了很多句柄管理类,通过它我们能得到真实的对象,从而完成操作,这在事件响应中很有用,如:

}

ASSERT( err != -1 ); m_hSipStack->process(fdset); while(dumUac->process());

return 0;

virtual void onNewSession(ServerInviteSessionHandle sis, InviteSession::OfferAnswerType oat, const SipMessage& msg) {

sis->provisional(180);// sis是ServerInviteSession的句柄实例,通过它我们得到ServerInviteSession对象,从而完成相关动作。 //。。。。。。 }

3.4 Resiprocate SIP Stack解析之消息流程

不管是SendMessage或者对RecvMessage都是把它首先放进先进先出的一个队列。给张图展示下先:

18

19

看看Transport(Transport.hxx)类中的成员变量就是它们的归属: Fifo mTxFifo; // owned by the transport Fifo& mStateMachineFifo; // passed in

在整个Resiprocate大家族中事务层概念的体现是TransactionUser类,而其真正的实例和管理类就是DialogUsageManager;从其:

class DialogUsageManager : public HandleManager, public TransactionUser 能看出来;HandleManager点出了DialogUsageManager的管理功能的本质,并且管理各种对象(Handle就是各类对象的句柄,关于后面会提到)。

首先要明白在整个Resiprocate系统中不管是我们发出或者收到的SIP Message都是放进了先进先出的队列然后不断轮询处理,这有点点点象Windows的消息系统,对应收发的消息Resiprocate提供事件通知的机制。

Message FiFo的大致流动走向如此:

Outgoing messages 的源码流动走向大致如下,以下是INVITE MESSAGE产生及其流动示例:

20