sh改写后的simplecall 运行的流程,非原版

1 : 在main 函数中 , 新建一个

pSimpleCall = tbnew CSimpleCall(CmdLineArgs);

接着再调用 Result = pSimpleCall->Init();  初始化数据库连接,

并且把自己 attach到CTBCMCLIB , 能够attach的前提是 继承自CTBCMCLibUser

Result = CTBCMCLib::Attach( this );

 

然后再 Result = pSimpleCall->Run();

 

2 : pSimpleCall->Run();  实际就是调用  CTBCMCLib::GetInstance()->Run(&mfQuit);

 

3:因为 CsimpleCall 的 定义是

class CSimpleCall
    : public CTBCMCLibUser
    , public ITBCAFServiceAlmMgmtClient            /* ALM (application launch management) client (being launched, shutdown, monitored by Toolpack OAM application) */
    , public ITBCAFServiceCmMgmtClient                /* CM (Configuration management) client (being notified when Toolpack configuration is reloaded) */
    , public ITBCMCFreeListener<CTBCMCLeg>            /* CTBCMCLeg free listener (we are responsible to free memory for terminated call legs) */
    , public ITBCMCFreeListener<ITBCAFCallFlow>    /* CTBCMCLeg free listener (we are responsible to free memory for terminated call flows) */


所以它能 接收到 calllegpresent 消息

 

四 :  在 Oncalllegpresent 事件里  , 判断NAP ,并根据NAP决定采用哪个 callplow

 

        else if (strNAP == "SIP1")
        {
            strCallFlow            = "TestCallee";
            strServiceTemplate    = "TestCallee";
        }

然后再根据  strServiceTemplate决定 new 一个什么样的callflow

        else if(strServiceTemplate == "TestCallee")
        {
            /*int rate[10] = {10, 30, 60, 120, 240, 480, 600, 1200, 2400, 3600};*/
            //int duration = rand() % rate[rand() % 10] + 3;
            int duration = rand() % 600 + 3;
            pCall = tbnew CVHTestCallee(duration, "prompt://DestNum", ConfigParams.mTextCDRFolder, this, this);
        }


最后调用此 pcall的 AddIncoming 和 InitCall 方法

Result = pCall->AddIncoming( in_LegId, ptrIncomingLegAttribute, ptrIncomingLegProtocolAttributes, ptrAcceptCallProtAttribute );
Result = pCall->InitCall(&pCall);

 *** 从 AddIncoming到 OnInitIncomingCallLeg 的顺序是 : 

   AddIncoming调用 CTBCAFCallFlow::CreateIncomingCallLeg,然后

      CTBCAFCallFlow::CreateIncomingCallLeg 调用 mpCallInterface->OnInitIncomingCallLeg

  

      final, 在 CTBCAFCallFlow::Construct 函数中, 早已写明:   mpCallInterface   = this;

五 : 因为pcall是继承自 CVHCallFlow 的子类,  在 CVHCallFlow 中 , override 了 OnInitIncomingCallLeg 事件 , 调用

ProcessEvents(in_pCallLeg, Event_OnInitCallLeg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

此处要重点说明: 不仅是 OnInitIncomingCallLeg 事件,实际上 , OnInitOutgoingCallLeg,OnInitCallLeg 等所有继承自CTBCAFCallFlow的事件都是类似这样的代码 :

TBX_RESULT CVHCallFlow::OnInitOutgoingCallLeg(PCTBCAFCallLeg in_pCallLeg, PCTBCMC_PROTOCOL_ATTRIBUTE io_pCreateCallProtocolAttribute)
{
TBCAF_MUTEX_GET_SCOPE_BEGIN(&mMutex)
    CAFCODE(CVHCallFlow::OnInitCallLeg)
    {
        ProcessEvents(in_pCallLeg, Event_OnInitCallLeg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        TBX_EXIT_SUCCESS(TBX_RESULT_OK);
    }
    CAFCODE_DEFAULT_HANDLE{}
    RETURN;
TBCAF_MUTEX_GET_SCOPE_END(&mMutex)
}

也就是说 , 处理过程全部转到了 ProcessEvents

六 : 然后在 CVHCallFlow的 ProcessEvents事件里 , 有这样的代码

                switch(mState)
                {
                case STATE_IncomingLeg:
                    result = StateIncomingLeg(in_pCallLeg, in_vhEvent, io_ppThis, in_ProtocolAttribute, in_Reason, in_pEvent, in_pError, in_pMediaProfile, in_pIVR_Reason, in_pMedia_Reason, in_CollectedDigitAttribute);
                    TBCAF_EXIT_ON_ERROR(result, "StateIncomingLeg failed");
                    break;


这里的 STATE_IncomingLeg 是 CVHCallFlow 子类构造函数的参数

所有继承自 CVHCallFlow 的子类 , 只需设置好自己的所有可能的state ,  并编写相应的 StateIncomingLeg(针对STATE_IncomingLeg 状态 ) ,以及其他 StateXXX 即可 。

并在何时的state里 , 真正把2个callLeg连接起来 。

 

 

 

----------------Q & A

1 : in CVHCCallFlow , 这三个变量

 

    LEG_INFO                        mLegA;
    LEG_INFO                        mLegB;
    LEG_INFO                        mLegIn;

是在何时得到赋值,分别代表什么?

A :

 

posted on 2014-11-04 17:55  齐文宣  阅读(306)  评论(0编辑  收藏  举报

导航