⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmcall.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
        default:
            break;
        }
        if (stateMode==cmCallStateModeDisconnectedNormal)
            /*The state mode still not determined properly*/
        {
            switch(call->state)
            {
                case cmCallStateInit:
                case cmCallStateDialtone:
                        stateMode=cmCallStateModeDisconnectedUnreachable;
                break;
                case cmCallStateProceeding:
                case cmCallStateRingBack:
                        stateMode=cmCallStateModeDisconnectedReject;
                break;
                case cmCallStateTransfering:
                case cmCallStateDisconnected:
                case cmCallStateIdle:
                    /*If we in one of this states, then we already reported the disconnected state*/
                    doNotReport=RV_TRUE;
                break;
            default:
                break;
            }
        }
        if (!doNotReport)
            notifyState((HCALL)call,state,stateMode);
    }
}

/************************************************************************
 * dropControl
 * purpose: Drop the H245 Control connection for a call.
 *          This function is used when calls are disconnected
 * input  : call    - Stack handle for the call
 * output : none
 * return : none
 ************************************************************************/
void dropControl(IN callElem* call)
{
    HCONTROL hCtrl;
    hCtrl = cmiGetControl((HCALL)call);

    /* See if we have to stop the control at all */
    if (m_callget(call, control))
    {
        /* First update the status so we don't get into stopControl() twice from 2 different
           threads: one on the incoming endSessionCommand and one for an outgoing one */
        m_callset(call, control, RV_FALSE);
        stopControl(hCtrl);
    }

    /* Close all channels of this call */
    closeChannels(hCtrl);
}

/************************************************************************
 * dropRas
 * purpose: Notify the gatekeeper the call was disconnected before finishing
 *          off with this call
 * input  : call    - Stack handle for the call
 * output : none
 * return : none
 ************************************************************************/
void dropRas(callElem*call)
{
    int ret = 0;
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);

    if (!emaWasDeleted((EMAElement)call))
    {
        if (!app->manualRAS && !m_callget(call,dummyRAS))
        {
            /* Automatic RAS - send DRQ on call if necessary */
            ret = cmiAutoRASCallDrop((HCALL)call);
        }

        if (app->manualRAS || m_callget(call,dummyRAS) || (ret < 0))
        {
            if (!app->manualRAS)
                cmiAutoRASCallClose((HCALL)call);

            /* Manual RAS - continue to drop the call */
            callStopOK(call);
        }
    }
}


int callStartError(callElem*call)
{
    dropControl(call);
    reportDisconnectedState(call,reasonDRQ);
    if (!m_callget(call,callInitiator))
        q931CallDrop(cmiGetQ931((HCALL)call),-1);
    /* If GK has rejected our call then just close the call*/
    /* No RAS drop required*/
    callStopOK(call);
    return 0;
}

int callIncompleteAddress(callElem*call)
{
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
    if (m_callget(call,callInitiator))
    {
        if (m_callget(call,enableOverlapSending))
        {
            if (app->cmMyCallEvent.cmEvCallIncompleteAddress)
            {
                int nesting;
                cmiCBEnter((HAPP)app,(char*)"cmEvCallIncompleteAddress(haCall=0x%p,hsCall=0x%p)",(HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
                nesting=emaPrepareForCallback((EMAElement)call);
                app->cmMyCallEvent.cmEvCallIncompleteAddress((HAPPCALL)emaGetApplicationHandle((EMAElement)call),(HCALL)call);
                emaReturnFromCallback((EMAElement)call,nesting);
                cmiCBExit((HAPP)app,(char*)"cmEvCallIncompleteAddress");
            }
        }
        else
        {
            dropControl(call);
            reportDisconnectedState(call,reasonDRQ);
            if (!m_callget(call,callInitiator))
                q931CallDrop(cmiGetQ931((HCALL)call),-1);
            /* If GK has rejected our call then just close the call*/
            /* No RAS drop required*/
            callStopOK(call);
            return RV_ERROR_NOTSUPPORTED;
        }
    }
    return RV_OK;
}

int callStartRoute(callElem*call)
{
    cmTransportAddress ta;
    if (!m_callget(call,callInitiator))
    {
        cmCallSetParam((HCALL)call,cmParamFacilityReason,0,cmReasonTypeRouteCallToGatekeeper,NULL);
        cmGetGKCallSignalAddress((HAPP)emaGetInstance((EMAElement)call),&ta);
        cmCallSetParam((HCALL)call,cmParamAlternativeAddress,0,0,(char*)&ta);
        q931CallFacility(cmiGetQ931((HCALL)call),-1);
    }
    else
        callStartError(call);
    return 0;
}

/************************************************************************
 * callDial
 * purpose: Dials a call or answers incoming Setup requests.
 *          This function checks if we have to ARQ the GK on this call or
 *          not and continues the call setup process.
 * input  : call    - Stack handle for the call to dial
 * output : none
 * return : negative on error
 ************************************************************************/
static int callDial(IN callElem* call)
{
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
    cmTransportAddress ta;
    m_callset(call,dummyRAS,RV_FALSE);

    if (app->manualRAS)
        m_callset(call,dummyRAS,RV_TRUE);
    else
    {
        if (call->preGrantedArqUse>=0)
        {
            /* PreGrantedARQ is used */
            if (m_callget(call,callInitiator))
            {
                /* Let's see if we've got a PreGranted call making on this outgoing call */
                if (app->rasGranted&makeCall)
                {
                    if ( !(app->rasGranted&useGKCallSignalAddressToMakeCall) && (call->preGrantedArqUse==cmPreGrantedArqDirect))
                    {
                        /*direct call without ARQ is allowed*/
                        if (cmCallGetParam((HCALL)call,cmParamDestCallSignalAddress,0,0,(char*)&ta)>=0)
                        {
                            cmCallSetParam((HCALL)call,cmParamDestinationIpAddress,0,0,(char*)&ta);
                        }
                        else
                        {
                            /*if not exist address do call via GK.*/
                            if (app->rasGrantedProtocol==1)
                            {
                                cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransUseAnnexE,NULL);
                                cmCallSetParam((HCALL)call,cmParamDestinationAnnexEAddress,0,0,(char*)&app->annexEAddress);
                            }
                            else
                            {
                                cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransNoAnnexE,NULL);
                                cmGetGKCallSignalAddress((HAPP)app,&ta);
                                cmCallSetParam((HCALL)call,cmParamDestinationIpAddress,0,0,(char*)&ta);
                            }
                        }
                    }
                    else
                    {
                        /*routed call without ARQ   */
                        if (app->rasGrantedProtocol==1)
                        {
                            cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransUseAnnexE,NULL);
                            cmCallSetParam((HCALL)call,cmParamDestinationAnnexEAddress,0,0,(char*)&app->annexEAddress);
                        }
                        else
                        {
                            cmCallSetParam((HCALL)call,cmParamAnnexE,0,cmTransNoAnnexE,NULL);
                            cmGetGKCallSignalAddress((HAPP)app,&ta);
                            cmCallSetParam((HCALL)call,cmParamDestinationIpAddress,0,0,(char*)&ta);
                        }
                    }
                    m_callset(call,dummyRAS,RV_TRUE);
                }
            }
            else if ((app->rasGranted&answerCall) && !(app->rasGranted&useGKCallSignalAddressToAnswer))
            {
                /* It's an incoming call and we can answer the Setup without an ARQ to the GK */
                m_callset(call,dummyRAS,RV_TRUE);
            }
        }
    }

    call->rate=call->newRate;

    if (!m_callget(call,dummyRAS))
    {
        /*Automatic RAS*/
        cmiAutoRASCallCreate((HCALL)call);
        return cmiAutoRASCallDial((HCALL)call);
    }
    else
    {
        /* 2004.12.24. fujiangdong. */
        HCALL hsCall = (HCALL)call;
        autorasEndpoint* autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
        autorasCall* autorascall = (autorasCall *)cmiGetAutoRas(hsCall);
		
        /* set the source addresses from the configuration. in automatic RAS, the ARQ will be set */
        if (cmCallGetParam(hsCall,cmParamFullSourceAddress,0,NULL,NULL)<0)
            cmCallSetParam(hsCall,cmParamFullSourceAddress,0,
                pvtGetChild2(app->hVal,app->rasConf,__q931(registrationInfo),__q931(terminalAlias)),NULL);

        autorascall->irrTimer = RvH323TimerStartPeriodic(autoras->hTimers, autoRasIrrTimeout, (void*)hsCall, 1000 * app->irrFrequencyInCall);
        /*cmiAutoRASCallSetUnsolicitedIRR((HCALL)call, app->irrFrequencyInCall);*/
        /* No need to deal with any RAS messages here - continue with the call */
        return callStartOK(call);
    }
}


/**********************************************************************
* cmSetupEnd
* This function is responsible for the end of the scenatio of receiving
* a setup message. It was taken out of the cmSetup in order to give the
* endpoint time to receive ACF before sending AutoConnect (when autoRas
* and autoConnect are on).
************************************************************************/
int cmSetupEnd(IN callElem* call)
{
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
    HPVT hVal=app->hVal;
    int autoAnswer, ret = 0;

    if (pvtGetChild(hVal,app->q931Conf,__q931(autoAnswer),NULL)>=0)
    {
        /* Configuration set to automatically answer any incoming call */
        autoAnswer = 1;
    }
    else
    {
        autoAnswer = 0;
        /* Check if we automatically send Alerting for incoming calls */
        if (m_callget(call,sendAlerting))
            q931CallAccept(cmiGetQ931((HCALL)call),-1);
    }

    /*If we are configured to answer the call automatically then do it*/
    if (autoAnswer && call->state!=cmCallStateConnected)
        ret = callAnswer(call);
    return ret;
}

int cmSetup(callElem*call, int message)
{
    int  ret;

    /* Check if we automatically send Call-Proceeding for incoming calls */
    if(m_callget(call,sendCallProceeding))
    {
        q931CallCallProceeding(cmiGetQ931((HCALL)call),-1);
        m_callset(call, enableOverlapSending, RV_FALSE);
    }

    /* We need to analize the fast start before sending the automatic CONNECT message back */
    if ((message >=0) && !emaWasDeleted((EMAElement)call))
    {
       RvInt32 establish=1;
        cmCallGetParam((HCALL)call,cmParamEstablishH245,0,&establish,NULL);
        if (establish)
            analyzeFastStartMsg(call, message);
    }

    ret = callDial(call);
    if ((ret >= 0) && (m_callget(call,dummyRAS)) && (call->state != cmCallStateWaitAddressAck))
        ret = cmSetupEnd(call);

    return ret;
}

int cmCallProceeding(callElem*call, int message)
{
    cmElem* app=(cmElem*)emaGetInstance((EMAElement)call);
    HPVT hVal=app->hVal;
    int tmpNodeId,tmpNodeId1;

    __pvtGetNodeIdByFieldIds(tmpNodeId,hVal,message,
                {_q931(message) _anyField _q931(userUser) _q931(h323_UserInformation)
                 _q931(h323_uu_pdu) _q931(h323_message_body) _anyField LAST_TOKEN});

    tmpNodeId1=pvtGetChild(hVal,tmpNodeId,__q931(destinationInfo),NULL);
    cmCallSetParam((HCALL)call,cmParamFullDestinationInfo,0,tmpNodeId1,NULL);

    notifyState((HCALL)call,cmCallStateProceeding,(cmCallStateMode_e)0);

    {
        int establish=1;
        cmCallGetParam((HCALL)call,cmParamEstablishH245,0,&establish,NULL);
        if (establish)
            if (cmFastStartReply(call,tmpNodeId) >= 0)
                deleteFastStart(call);
    }
    return 0;
}

int cmAlerting(callElem*call, int message)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -