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

📄 cmautorascall.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
 *          trStage - Stage of response
 * output : none
 * return : non-negative value on success
 *          negative value on failure
 ************************************************************************/
int RVCALLCONV autoRasRegAndSendAftDisc
(
 IN  HAPPRAS          haRas,
 IN  HRAS             hsRas,
 IN  cmRASTrStage     trStage
)
{
    int ret=RV_ERROR_UNKNOWN, responseId = cmiRASGetResponse(hsRas);
    autorasCall* autorasC = (autorasCall *)haRas;
    HCALL hsCall = cmiGetByAutoRas((HAUTORASCALL)autorasC);
    autorasEndpoint* autorasE = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));

    switch(trStage)
    {
    case cmRASTrStageConfirm:
        {
            /* cool, now let's send the RRQ. first we have to get the address */
            int tmpNodeId;
            cmTransportAddress GkAddr;
            cmRASAlias * GkIdPtr = NULL;
            cmRASAlias GkId;
            char IdSrt[128];
            GkId.string = IdSrt;

            __pvtGetByFieldIds(tmpNodeId, autorasE->hVal, responseId,
                { _q931(gatekeeperConfirm) _q931(rasAddress) LAST_TOKEN }, NULL, NULL, NULL);
            cmVtToTA(autorasE->hVal, tmpNodeId, &GkAddr);

            __pvtGetByFieldIds(tmpNodeId, autorasE->hVal, responseId,
                { _q931(gatekeeperConfirm) _q931(gatekeeperIdentifier) LAST_TOKEN }, NULL, NULL, NULL);
            if(tmpNodeId>=0)
            {
                GkIdPtr = &GkId;
                GkId.length = (unsigned short) pvtGetString(autorasE->hVal, tmpNodeId, 128, IdSrt);
            }

            cmRASClose(hsRas);
            autorasE->registrationTx = NULL;
            ret = autoRasRegAndSend(autorasE, autorasC, &GkAddr, GkIdPtr);
            return ret;
        }
    case cmRASTrStageReject:
        autorasC->wasRejected = RV_TRUE;
    case cmRASTrStageTimeout:
        {
            /* Let's register to the next GK */
            if((ret = autoRasCallSendToNextGK(autorasE, autorasC)) < 0)
            {
                /* Drek. could not send the ARQ, maybe because there are no more GKs. */
                if(autorasC->wasRejected)
                {
                    autorasC->wasRejected = RV_FALSE;
                    autorasC->isTempRdrn = RV_FALSE;
                    autorasE->event(hsCall, hsRas, cmiAutoRasEvCallRejected);
                    break;
                }

                autorasE->event(hsCall, hsRas, cmiAutoRasEvTimedout);

                /* See if we should try to register again */
                if(autorasC->isTempRdrn)
                {
                    /* just a temp redirection, forget it */
                    autorasC->isTempRdrn = RV_FALSE;
                    break;
                }
                if (pvtGetChild(autorasE->hVal, autorasE->confNode, __q931(dontRegisterOnTimeout), NULL) < 0)
                {
                    /* We should change the status to not registered */
                    autorasE->state = cmIdle;
                    autoRasCallIdleState(autorasE, autorasC);

                    /* Make sure we're trying to register again */
                    if ((autorasE->internalState != autorasRegTrying) && (autorasE->internalState != autorasRegFailed))
                        cmRegister(autorasE->hApp);
                }
            }
        }

    default:
        /* This shouldn't happen... */
        break;
    }
    if (hsRas == autorasE->registrationTx)
    {
        cmRASClose(hsRas);
        autorasE->registrationTx = NULL;
    }
    return ret;
}

/************************************************************************
 * autoRasDiscRegAndSend
 * purpose: Send GRQ for an Alt Gk which answered with discoveryRequired
 * input  : autorasE    - Automatic RAS module for an EP
 *          autorasC    - Automatic RAS module for a call
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int autoRasDiscRegAndSend
(
    IN autorasEndpoint* autorasE,
    IN autorasCall* autorasC
)
{
    int ret, tmpNode;
    cmTransportAddress GkAddr;
    int GKnode = autoRasGetCurrentAltGkNode(autorasE, autorasC);

    if (GKnode<0)
        /* SHOULD NOT BE HERE !! */
        return RV_ERROR_UNKNOWN;
    tmpNode = pvtGetChild(autorasE->hVal, GKnode, __q931(rasAddress), NULL);
    if(tmpNode>=0) cmVtToTA(autorasE->hVal, tmpNode, (cmTransportAddress *) &GkAddr);


    if (autorasE->registrationTx != NULL)
    {
        cmRASClose(autorasE->registrationTx);
        autorasE->registrationTx = NULL;
    }
    ret = cmRASStartTransaction(autorasE->hApp, (HAPPRAS)autorasC,
        &autorasE->registrationTx, cmRASGatekeeper, &GkAddr, NULL);

    if (ret >= 0)
    {
        cmAlias GKID;
        char GKIDstr[128];
        int GKIDnode = pvtGetChild(autorasE->hVal, GKnode, __q931(gatekeeperIdentifier), NULL);
        GKID.string = GKIDstr;

        if((GKIDnode>=0) &&
            ((GKID.length = (unsigned short) pvtGetString(autorasE->hVal, GKIDnode, 128, GKIDstr))>0))
            cmRASSetParam(autorasE->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(GKID), (char *)&GKID);

        /* Set the parameters of the message */
        cmRASSetParam(autorasE->registrationTx, cmRASTrStageRequest, cmRASParamDiscoveryComplete, 0, (RvInt32)autorasE->discoveryComplete, NULL);
        cmRASSetParam(autorasE->registrationTx, cmRASTrStageRequest, cmRASParamKeepAlive, 0, 0, NULL);

        /* Make sure next time we know nothing about a GCF */
        autorasE->discoveryComplete = RV_FALSE;

        /* Set the response handler for this message */
        cmiRASSetTrEventHandler(autorasE->registrationTx, autoRasRegAndSendAftDisc);

        /* Send the request */
        ret = cmRASRequest(autorasE->registrationTx);
    }

    return ret;
}

/************************************************************************
 * autoRasIrrTimeout
 * purpose: Callback function which sends an unsolicited IRR on a call
 * input  : context - autoras call handle
 * output : none
 * return : none
 ************************************************************************/
RvBool autoRasIrrTimeout(IN void* context)
{
    HCALL hsCall = (HCALL)context;
    autorasEndpoint* autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
    autorasCall* call = (autorasCall *)cmiGetAutoRas(hsCall);
    int res;

    /* Create an IRR transaction and fill it in with the call's information
        We're leaving this transaction open as we're sending it on each timeout
        event for the IRR */
    if (call->irrTx != NULL)
        cmRASClose(call->irrTx);

    res = cmRASStartTransaction(autoras->hApp, (HAPPRAS)call, &call->irrTx,
                cmRASUnsolicitedIRR, NULL, hsCall);

    if (res >= 0)
    {
        cmRASRequest(call->irrTx);
    }
    return RV_TRUE;
}


/************************************************************************
 * autoRasCallTransaction
 * purpose: Callback function used for automatic RAS for dealing with
 *          incoming transactions related to specific calls
 * input  : hApp        - Stack instance handle
 *          hsRas       - Stack's handle for the RAS transaction
 *          hsCall      - Stack's call handle
 *          transaction - The type of transaction that arrived
 *          srcAddress  - Address of the source
 *          haCall      - Application's call handle
 *          notifyCb    - Callback for application about the request
 * output : none
 * return : RV_TRUE if message was processed by this callback and shouldn't
 *          be processed by the manual RAS callbacks
 *          RV_FALSE if message wasn't processed by this callback
 ************************************************************************/
RvBool RVCALLCONV autoRasCallTransaction(
    IN  HAPP                hApp,
    IN  HRAS                hsRas,
    IN  HCALL               hsCall,
    IN  cmRASTransaction    transaction,
    IN  cmRASTransport*     srcAddress,
    IN  HAPPCALL            haCall,
    IN  cmEvAutoRASRequestT notifyCb)
{
    autorasCall* call = (autorasCall *)cmiGetAutoRas(hsCall);
    if (haCall || srcAddress);

    /* Notify the application if we have to */
    if (notifyCb != NULL)
    {
        switch (transaction)
        {
            case cmRASDisengage:
            case cmRASBandwidth:
            case cmRASInfo:
                cmiCBEnter(hApp, "cmEvAutoRASRequest(hsRas=0x%p,hsCall=0x%p,trans=%d)", hsRas, hsCall, transaction);
                notifyCb(hsRas, hsCall, transaction, srcAddress, haCall);
                cmiCBExit(hApp, "cmEvAutoRASRequest(hsRas=0x%p)", hsRas);
                break;
            default:
                /* Not through automatic RAS... */
                break;
        }
    }

    /* See what we've got */
    if (emaLock((EMAElement)hsCall))
    {
        switch (transaction)
        {
            case cmRASDisengage:
            {
                /* DRQ - automatically confirm it */
                autorasEndpoint* autoras;
                autorasCallState state = call->callState;
                call->callState = autorasCallDisconnecting;
                autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));

                /* Always send DCF on this one and close the transaction */
                cmRASConfirm(hsRas);
                cmRASClose(hsRas);

                /* We should get back to the idle state of the transaction */
                autoRasCallIdleState(autoras, call);

                if (state != autorasCallDisconnecting)
                {
                    /* Notify application about this situation */
                    autoras->event(hsCall, hsRas, cmiAutoRasEvCallDropForced);
                }
                break;
            }

            case cmRASBandwidth:
            {
                /* BRQ - always confirm it */
                autorasEndpoint* autoras;
                autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));
                autoras->event(hsCall, hsRas, cmiAutoRasEvRateChanged);
                cmRASConfirm(hsRas);
                cmRASClose(hsRas);
                break;
            }

            case cmRASInfo:
            {
                /* IRQ on call - always confirm it */
                cmRASConfirm(hsRas);
                cmRASClose(hsRas);
                break;
            }

            default:
            {
                /* Not processed by automatic RAS */
				
                /* 2004.11.03, added. make sure we unlock the mutex */
                emaUnlock((EMAElement)hsCall);
				
                return RV_FALSE;
            }
        }
        emaUnlock((EMAElement)hsCall);
    }

    /* Make sure manual RAS knowns we have processed this mesage */
    return RV_TRUE;
}

/************************************************************************
 * autoRasBandwidthResponse
 * purpose: Callback function invoked when a response for BRQ arrives
 * input  : haRas   - Application's handle (autoras in this context)
 *          hsRas   - RAS Transaction handle
 *          trStage - Stage of response
 * output : none
 * return : non-negative value on success
 *          negative value on failure
 ************************************************************************/
int RVCALLCONV autoRasBandwidthResponse
(
    IN  HAPPRAS          haRas,
    IN  HRAS             hsRas,
    IN  cmRASTrStage     trStage)
{
    autorasEndpoint* autoras;
    autorasCall* call = (autorasCall *)haRas;
    HCALL hsCall = cmiGetByAutoRas((HAUTORASCALL)call);
    int rv = RV_ERROR_UNKNOWN;
    int responseId = cmiRASGetResponse(hsRas);

    if (emaLock((EMAElement)hsCall))
    {

        autoras = (autorasEndpoint *)cmiGetAutoRasHandle((HAPP)emaGetInstance((EMAElement)hsCall));

        /* See what we've got for the BRQ */
        switch(trStage)
        {
            case cmRASTrStageConfirm:
            {
                /* this function will set the new GK if needed, and get the new AltGKs list */
                setRasAlternateGatekeeper(autoras, call,
                    pvtGetChild(autoras->hVal, responseId, __q931(alternateGatekeeper), NULL));
                break;
            }

            case cmRASTrStageReject:
            {
                int chNodeId;

                /* See if this is a redirection */
                __pvtGetNodeIdByFieldIds(chNodeId, autoras->hVal, responseId, {_anyField _q931(altGKInfo) LAST_TOKEN});
                if (chNodeId >= 0)
                {
                    /* Se we are redirected to an AltGK.*/
                    RvInt32 isPerm;
                    int newAltGKs;

                    call->wasRejected = RV_TRUE;

                    /* maybe we are already working on a redirection */
                    if(!autoRasIsInSearch(autoras,call))
                    {
                        /* We're not working on anything right now  - we start redirection */
                        /* Let's see if permanently of temporeraly */
                        newAltGKs = pvtGetChild(autoras->hVal, chNodeId, __q931(alternateGatekeeper), NULL);
                        pvtGetChildByFieldId(autoras->hVal, chNodeId, __q931(altGKisPermanent), &isPerm, NULL);
                        if(isPerm)
                            autoRasSetPermList(autoras, newAltGKs);
                        else
                        {
                            call->isTempRdrn = RV_TRUE;
                            autoRasSetTempList(autoras, newAltGKs);
                        }
                    }
                    /* ok, let's send the old messsage to a new GK */
                    if(autoRasCallSendToNextGK(autoras, call) >= 0)
                    {
                        /* Sent ok */
                        /* Make sure we close this transaction if it wasn't already closed */
                        emaUnlock((EMAElement)hsCall);
                        return 0;
                    }
                    else
                    { /* Otherwise we are rejected for good */
                        call->isTempRdrn = RV_FALSE;
                        call->wasRejected = RV_FALSE;
                        autoRasResetSearch(autoras,NULL);
                    }
                }
                else
                    setRasAlternateGatekeeper(autoras, call, -1);
                break;
            }

            case cmRASTrStageTimeout:
            {
                /* timedout... */
                cmElem* app = (cmElem *)emaGetInstance((EMAElement)hsCall);

                /* maybe we are already working on a redirection, or

⌨️ 快捷键说明

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