subManager = new SubscribeManager( mySipStack );
if ( UaConfiguration::instance()->getSubscribeOn() )
{
cpLog( LOG_DEBUG, "Create Feature Thread" );
//这里建立一个向FS发送消息的线程,关于这个部分的内容在Feature //Server的部分再做详细介绍.
featureThread = new FeatureThread( subManager );
assert( featureThread != 0 );
uaBuilder->setSubscribeManager( subManager );
}
}
else
{
… …
}
// 是否打开重传机制?
if (UaCommandLine::instance( ) -> getBoolOpt( "retransmit" ) )
{
SipTransceiver::reTransOn();
}
else
{
SipTransceiver::reTransOff();
}
// 定义接收代理服务器(Proxy)发出的消息所储存的容器
myCallContainer = new UaCallContainer;
assert( myCallContainer != 0 );
//绑定容器到用户端
uaBuilder->setCallContainer( myCallContainer );
//设置SIP的消息堆栈
uaBuilder->setSipStack( mySipStack );
//开始向注册服务器发送注册(Register)消息。
uaBuilder->startRegistration();
}
2.3 HeartLessProxy的创建:
HeartLessProxy
(
const Sptr < Builder > builder,
unsigned short defaultSipPort,
Data applName,
bool filterOn,
bool nat,
SipAppContext aContext
)
{
myCallContainer = new CallContainer;
myBuilder = builder;
myBuilder->setCallContainer(myCallContainer);
//这里创建了一个消息的输出队列,在前面的创建一个UserAgent的实体的过程中已经
//阐述过会把它绑定到相关的设备上去
myCallProcessingQueue = new Fifo < Sptr < SipProxyEvent > >;
//这里创建一个WorkThread线程在该线程中的myBuilder->process(nextEvent)
//检查消息队列myFifo中的返回消息(调用Uabuilder->process进行检查),从而
//得到返回的消息。
//很明显,这里新创建了一个 myWorkerThread工作线程,我们等一下就会看到如何把它Run
//起来
myWorkerThread = new WorkerThread(myCallProcessingQueue, myBuilder);
//创建一个SIP消息收发器的实体,在这个实体的构建里主要是把收发SIP消息的TCP/UDP
//的收发通道创建(SipUdpConnection和SipUdpConnection)。同时会构造一个SNMP的
//SipAgent.他的主要作用是向SNMP网关发送SNMP消息,描述网络的运行状态
if ( filterOn == true )
{
mySipStack = new SipTransceiverFilter(applName, defaultSipPort, nat, aContext);
}
else
{
mySipStack = new SipTransceiver(applName, defaultSipPort, nat, aContext);
}
myBuilder->setSipStack(mySipStack);
//创建一个SIP消息的解析线程 。
mySipThread = new SipThread(mySipStack, myCallProcessingQueue);
… …
}
2.4 让User Agent Run起来:
构建User Agent的工作已经完毕,现在应该让调用它的Run方法了;从下面的程序可以看到,Run方法的调用,让整个程序进入一种"Idle"的状态,等待命令输入和状态的产生,这个过程我们可以看到在Ua.CXX的Main程序中调用(ua.run())。
Void UserAgent::run()
{
//调用HeartLessProxy的Run方法,稍后做详细的介绍
HeartLessProxy::run();
… …
deviceThread->run(); //调用SoundcardDevice::hardwareMain(0)
… …
rtpThread->run();//调用SoundCardDevice::processRTP()进行RTP流的处理
… …
//在这里向FS发送队列(myQ = new Fifo < Sptr < SubscribeMsg > >)中的各种消息,不
//过在Ua1001.cfg中,参数Subscribe_on设置为OFF所以,本章我们对FS暂不予以分析,
//在最后一章详细分析FS的时候回着重分析它.
featureThread->run();//调用subscribeManager::subscribeMain()
… …
//后台监测线程开启.
loadGenThread->run();//调用LoadGenMonitor::lgMain()
// User TimerEvent to kick start the load generator
… …
} // UserAgent::run
(未完待续)
作者供稿 CTI论坛编辑
作者联系方法:lu_zheng@21cn.com
在Vovida的基础上实现自己的SIP协议栈(二)