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

📄 cmautorasep.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
/************************************************************************
 * autoRasPrepareGRQ
 * purpose: Send a GRQ message to a gatekeeper trying to register it
 * input  : autoras - Automatic RAS instance to register
 * output : none
 * return : non-negative value on success
 *          negative value on failure
 ************************************************************************/
static int autoRasPrepareGRQ(IN autorasEndpoint* autoras)
{
    int ret;
    int GKnode = RV_ERROR_UNKNOWN;
    cmRASTransport GKAddr;
    cmRASTransport * GKAddrPtr = NULL;

    /* Make sure we have no pending transactions */
    if (autoras->registrationTx != NULL)
    {
        cmRASClose(autoras->registrationTx);
        autoras->registrationTx = NULL;
    }

    if(autoRasGotPermList(autoras))
    {
        GKnode = autoRasGetCurrentAltGkNode(autoras,NULL);
        if(GKnode < 0)
        { /* no more GKs in AltGKs list - get rid of it */
            autoRasRemovePermList(autoras);
            autoRasResetSearch(autoras,NULL);
        }
        else
        { /* Got a GK from the list - Get it's address */
            int GKAddrNode = pvtGetChild(autoras->hVal, GKnode, __q931(rasAddress), NULL);
            if((GKAddrNode>=0) && (cmVtToTA(autoras->hVal, GKAddrNode, (cmTransportAddress *) &GKAddr)>=0))
                GKAddrPtr = &GKAddr;
        }
    }
    /* Create the transaction - default destination (=gk) or the one we found */
    ret = cmRASStartTransaction(autoras->hApp, (HAPPRAS)autoras, &autoras->registrationTx, cmRASGatekeeper, GKAddrPtr, NULL);

    if (ret >= 0)
    {
        if(GKnode < 0)
        { /* not using AltGK. send a multicast request */
            /* Set the multicast parameter to indicate this as a multicast message */
            cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamMulticastTransaction, 0, RV_TRUE, NULL);
        }
        else
        { /* using an AltGK */
            /* Set the Gatkeeper ID to the indicated one (if indicated) */
            cmAlias GKID;
            char GKIDstr[128];
            int GKIDnode = pvtGetChild(autoras->hVal, GKnode, __q931(gatekeeperIdentifier), NULL);
            GKID.string = GKIDstr;
            if((GKIDnode>=0) &&
                ((GKID.length = (unsigned short) pvtGetString(autoras->hVal, GKIDnode, 128, GKIDstr))>0))
                cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(GKID), (char *) &GKID);
        }

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

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

        if (ret < 0)
        {
            /* We're not going to get any events on this transaction. We might as well
               just simulate waiting for a result and timing-out on that one to continue
               on trying */
            rasModule * rasMdl = (rasModule *)cmiGetRasHandle(autoras->hApp);
            int timeout;

            timeout = rasCfgGetTimeout(rasMdl) * rasCfgGetRetries(rasMdl);

            RvH323TimerCancel(autoras->hTimers, &autoras->regTimer);
            autoras->regTimer = RvH323TimerStart(autoras->hTimers, autorasTryToRegisterOnError, autoras, timeout);
        }
    }

    return ret;

}


/************************************************************************
 * autoRasPrepareRRQ
 * purpose: Send an RRQ message to a gatekeeper trying to register it
 * input  : autoras  - Automatic RAS instance to register
 *           GkNodeId - Node Id of Alt GK to try, RV_ERROR_UNKNOWN if none.
 * output : none
 * return : non-negative value on success
 *           negative value on failure
 ************************************************************************/
static int autoRasPrepareRRQ(IN autorasEndpoint* autoras, IN int GkNodeId)
{
    int ret;
    cmRASTransport GKAddr;
    cmTransportAddress * addrPtr = NULL;

    /* Make sure we have no pending transactions */
    if (autoras->registrationTx != NULL)
    {
        cmRASClose(autoras->registrationTx);
        autoras->registrationTx = NULL;
    }

    /* Check to see if this is a redirection */
    if(GkNodeId >=0 )
    {
        /* Got a GK - Get it's address */
        int GKAddrNode = pvtGetChild(autoras->hVal, GkNodeId, __q931(rasAddress), NULL);
        if((GKAddrNode>=0) && (cmVtToTA(autoras->hVal, GKAddrNode, (cmTransportAddress *) &GKAddr)>=0))
            addrPtr = &GKAddr;
    }
    /* Maybe we already found an Alt GK */
    else
        if(autoras->setGK.port)
            addrPtr = &autoras->setGK;

    /* Create the transaction - default destination (=gk) or the AltGK we found */
    ret = cmRASStartTransaction(autoras->hApp, (HAPPRAS)autoras, &autoras->registrationTx, cmRASRegistration, addrPtr, NULL);

    if (ret >= 0)
    {
        cmAlias GKID;
        char GKIDstr[128];
        GKID.string = GKIDstr;

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

        /* Check to see if this is a redirection */
        if(GkNodeId >=0)
        {
            /* Set the Gatkeeper ID to the indicated one (if indicated) */
            int GKIDnode = pvtGetChild(autoras->hVal, GkNodeId, __q931(gatekeeperIdentifier), NULL);
            if((GKIDnode>=0) &&
               ((GKID.length = (unsigned short) pvtGetString(autoras->hVal, GKIDnode, 128, GKIDstr))>0))
                cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(GKID), (char *) &GKID);
        }
        /* Maybe we already found an Alt GK */
        else if(autoras->GKID.length)
            cmRASSetParam(autoras->registrationTx, cmRASTrStageRequest, cmRASParamGatekeeperID, 0, sizeof(autoras->GKID), (char *) &autoras->GKID);

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

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

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

        if (ret < 0)
        {
            /* We're not going to get any events on this transaction. We might as well
               just simulate waiting for a result and timing-out on that one to continue
               on trying */
            rasModule * rasMdl = (rasModule *)cmiGetRasHandle(autoras->hApp);
            int timeout;

            timeout = rasCfgGetTimeout(rasMdl) * rasCfgGetRetries(rasMdl) * 1000;

            RvH323TimerCancel(autoras->hTimers, &autoras->regTimer);
            autoras->regTimer = RvH323TimerStart(autoras->hTimers, autorasTryToRegisterOnError, autoras, timeout);
        }
    }

    return ret;
}


/************************************************************************
 * autoRasTryToRegister
 * purpose: Start registration process of the endpoint
 * input  : autoras - Automatic RAS instance to register
 * output : none
 * return : non-negative value on success
 *          negative value on failure
 ************************************************************************/
static int autoRasTryToRegister(IN autorasEndpoint* autoras)
{
    RvInt32 maxFail;
    int status;

    if (autoras->internalState != autorasRegFailed)
        autoras->internalState = autorasRegTrying;
    autoras->regTries++; /* another try... */

    /* Make sure we reset the timer if we have any */
    RvH323TimerCancel(autoras->hTimers, &autoras->regTimer);

    /* Make sure we have no pending transactions */
    if (autoras->registrationTx != NULL)
    {
        cmRASClose(autoras->registrationTx);
        autoras->registrationTx = NULL;
    }

    /* See if we're done trying */
    /* ToDo: compensate for AltGKs */
    if ((pvtGet(autoras->hVal, pvtGetChild(autoras->hVal, autoras->confNode, __q931(maxFail), NULL), NULL, NULL, &maxFail, NULL) < 0) || (maxFail == 0))
        maxFail = 1;
    if ((autoras->regTries > maxFail) && (autoras->internalState != autorasRegFailed))
    {
        autoras->internalState = autorasRegFailed;
        /* We continue on trying to register although we failed - here, we just allow calls
           to be created */

        /* Notify the application that we're not registered although the user wanted to */
        status = autoRasChangeState(autoras, cmRegistrationConfirm, RV_PVT_INVALID_NODEID);

        /* In case someone called cmUnregister or cmRegister in the callback, do not send another RRQ */
        if ( (autoras->internalState == autorasRegNotTried) || (autoras->internalState == autorasRegTrying) )
            return 0;
    }

    /* See if we're in GRQ or RRQ */
    __pvtGetByFieldIds(status, autoras->hVal, autoras->confNode, {_q931(manualDiscovery) _q931(defaultGatekeeper) LAST_TOKEN}, NULL, NULL, NULL)
    if ((status >= 0) && (!autoras->discoveryRequired))
    {
        /* We've got a GK address that didn't reject us yet - start from RRQ */
        return autoRasPrepareRRQ(autoras, RV_ERROR_UNKNOWN);
    }
    else
    {
        /* We don't have any GK address, or were rejected by GK - start from GRQ */
        if(autoRasGotPermList(autoras))
        {
            /* We are using Alt GKs - be sure to try the next one */
            autoRasGetNextAltGkNode(autoras,NULL);
        }
        return autoRasPrepareGRQ(autoras);
    }
}


/************************************************************************
 * autorasTryToRegisterOnError
 * purpose: Timeout function after simulating a timeout on a transaction
 *          that we couldn't get started properly.
 * input  : context - Automatic RAS handle
 * output : none
 * return : none
 ************************************************************************/
static RvBool autorasTryToRegisterOnError(IN void* context)
{
    autorasEndpoint *autoras = (autorasEndpoint *)context;

    /* Reset the timer if we have any */
    RvH323TimerClear(autoras->hTimers, &autoras->regTimer);

    /* Try to register all over again */
    autoRasTryToRegister(autoras);

    return RV_FALSE;
}


/************************************************************************
 * autoRasIdleAndRegister
 * purpose: Change the state of the Automatic RAS endpoint handling to
 *          idle and retry registration
 * input  : autoras - Automatic RAS handle
 * output : none
 * return : non-negative value on success
 *          negative value on failure
 ************************************************************************/
static void autoRasIdleAndRegister(IN autorasEndpoint* autoras)
{
    /* Change the state back to Idle if we have to */
    if (autoras->state != cmIdle)
    {
        autoras->state = cmIdle;
        autoras->internalState = autorasRegTrying;
        autoRasChangeState(autoras, (cmRegEvent)-1, RV_PVT_INVALID_NODEID);
        if(autoras->internalState == autorasRegNotTried)
            /* someone decided to unregister in the above event */
            return;
    }

    /* Try to register again */
    autoRasTryToRegister(autoras);
}


/************************************************************************
 * autoRasEPTransaction
 * purpose: Callback function that handles incoming endpoint-related
 *          transactions
 * input  : hApp        - Stack instance handle
 *          hsRas       - RAS transaction handle
 *          transaction - Transaction type of incoming message
 *          srcAddress  - Address of the message's origin
 *          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
 ************************************************************************/
static RvBool RVCALLCONV autoRasEPTransaction(
    IN  HAPP                hApp,
    IN  HRAS                hsRas,
    IN  cmRASTransaction    transaction,
    IN  cmRASTransport*     srcAddress,
    IN  cmEvAutoRASRequestT notifyCb)
{
    if (srcAddress); /* Remove warning from compilation */

    /* Tell the application about this request... */
    if (notifyCb != NULL)
    {
        switch (transaction)
        {
        case cmRASUnregistration:
        case cmRASNonStandard:
        case cmRASInfo:
            cmiCBEnter(hApp, "cmEvAutoRASRequest(hsRas=0x%p,hsCall=0x0,trans=%d)", hsRas, transaction);
            notifyCb(hsRas, NULL, transaction, srcAddress, NULL);
            cmiCBExit(hApp, "cmEvAutoRASRequest(hsRas=0x%p)", hsRas);
            break;
        default:
            /* Not handled by Automatic RAS... */
            break;

        }
    }

    /* Check the type of transaction we're dealing with */
    switch (transaction)
    {
    case cmRASUnregistration:
        {
            /* URQ message - always send back a UCF */
            autorasEndpoint* autoras = (autorasEndpoint *)cmiGetAutoRasHandle(cmiRASGetHAPP(hsRas));
            int requestId = cmiRASGetRequest(hsRas);
            int nodeId;
            int newAltGKs = RV_ERROR_UNKNOWN;

            /* First - let's move to idle */
            autoras->state = cmIdle;
            autoRasChangeState(autoras, cmUnregistrationRequest, requestId);

            /* now, let's confirm it */
            cmRASConfirm(hsRas);

            /* Now see if we were redirected */
            __pvtGetNodeIdByFieldIds(newAltGKs, autoras->hVal, requestId, {_anyField _q931(alternateGatekeeper) LAST_TOKEN});
            if (newAltGKs >= 0)
            {
                /* Se we are redirected to an AltGK.*/
                /* maybe we are already working on a redirection */
                if(autoRasIsInSearch(autoras,NULL))
                {
                    /* We're working on a redirection, but we'd like to reset it */
                    autoRasSetPermList(autoras, newAltGKs);
                    autoRasResetSearch(autoras, NULL);
                    autoras->isTempRdrn = RV_FALSE;
                    autoRasRemoveTempList(autoras);
                    cmRASClose(hsRas);
                    if(autoras->registrationTx)
                    {
                        cmRASClose(autoras->registrationTx);
                        autoras->registrationTx = 0;
                    }
                }
                else
                {
                    autoRasSetPermList(autoras, newAltGKs);
                    autoRasRemoveTempList(autoras);
                }
                /* we're starting redirection: let's get a gatekeeper */

⌨️ 快捷键说明

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