• 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 :

  • 相关阅读:
    工作问题:http下载文件,中文文件名在firefox下乱码问题
    Error:不能将"char*"类型的值分配到"LPSTR"类型的实体 也许 "char*"类型的实参与"LPCWSTR"类型的形参不兼容
    Kryonet client disconnects after send a packet to server (java)
    NetBeans Support Weblog
    When Deep Learning Meets Data Alignment: A Review on Deep Registration Networks (DRNs)
    DeepFakes and Beyond: A Survey of Face Manipulation and Fake Detection
    Sketch-to-Art: Synthesizing Stylized Art Images From Sketches
    (转载)除了 MSE loss,也可以试试用它:SSIM 的原理和代码实现
    Face X-ray for More General Face Forgery Detection
    FaceShifter: Towards High Fidelity And Occlusion Aware Face Swapping
  • 原文地址:https://www.cnblogs.com/lthxk-yl/p/4032344.html
Copyright © 2020-2023  润新知