利用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
TestUac uac;
16
dumUac->setInviteSessionHandler(&uac); dumUac->setClientRegistrationHandler(&uac); dumUac->addOutOfDialogHandler(OPTIONS, &uac);
auto_ptr
//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
在整个Resiprocate大家族中事务层概念的体现是TransactionUser类,而其真正的实例和管理类就是DialogUsageManager;从其:
class DialogUsageManager : public HandleManager, public TransactionUser 能看出来;HandleManager点出了DialogUsageManager的管理功能的本质,并且管理各种对象(Handle就是各类对象的句柄,关于后面会提到)。
首先要明白在整个Resiprocate系统中不管是我们发出或者收到的SIP Message都是放进了先进先出的队列然后不断轮询处理,这有点点点象Windows的消息系统,对应收发的消息Resiprocate提供事件通知的机制。
Message FiFo的大致流动走向如此:
Outgoing messages 的源码流动走向大致如下,以下是INVITE MESSAGE产生及其流动示例:
20