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

📄 rasin.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
            if (tx->transactionType == cmRASInfo)
            {
                RvPvtNodeId irrNode = pvtAdd(ras->hVal, tx->txProperty, __q931(response), 0, NULL, NULL);
                rasSetIrrFields(ras, (HRAS)tx, irrNode, tx->hsCall);
            }

            if (ras->evCallRequest != NULL)
            {
                /* Associate message context with transaction */
                tx->hMsgContext = *hMsgContext;
                *hMsgContext = NULL;

                notifyApp = !ras->evCallRequest(ras->app,
                                                (HRAS)tx,
                                                tx->hsCall,
                                                tx->transactionType,
                                                srcAddress,
                                                haCall,
                                                ras->evAutoRas.cmEvAutoRASRequest);
            }
        }
        else
        {
            if (ras->evEpRequest != NULL)
            {
                /* Associate message context with transaction */
                tx->hMsgContext = *hMsgContext;
                *hMsgContext = NULL;
                notifyApp = !ras->evEpRequest(ras->app,
                                              (HRAS)tx,
                                              tx->transactionType,
                                              srcAddress,
                                              ras->evAutoRas.cmEvAutoRASRequest);
            }

        }

        if (notifyApp)
        {
            if (ras->evApp.cmEvRASRequest != NULL)
            {
                /* Associate message context with transaction */
                tx->hMsgContext = *hMsgContext;
                *hMsgContext = NULL;
                cmiCBEnter(ras->app, "cmEvRASRequest(hsRas=0x%p,hsCall=0x%p,trans=%d)", tx, tx->hsCall, tx->transactionType);
                ras->evApp.cmEvRASRequest((HRAS)tx,
                                          tx->hsCall,
                                          &haRas,
                                          tx->transactionType,
                                          srcAddress,
                                          haCall);
                cmiCBExit(ras->app, "cmEvRASRequest(hsRas=0x%p,haRas=0x%p)", tx, haRas);

                /* Update the application's handle */
                emaSetApplicationHandle((EMAElement)tx, (void*)haRas);
            }
            else
            {
                /* Automatic RAS mode, and there's no callback for manual RAS messages.
                   We should kill this transaction. */
                status = rasCloseInTx(ras, tx);
            }
        }

        /* Release the transaction when we're done */
        emaRelease((EMAElement)tx);
    }
    else
    {
        /* This is a retransmission - see if we have a reply for it */
        emaLock((EMAElement)tx);
        RvLockRelease(&ras->lockInHash);

        switch (tx->state)
        {
            case rasTxStateReplySent:
                /* Retransmit the reply to the sender */
                status = rasRetransmit(ras, (HRAS)tx, tx->encodedMsg, &tx->destAddress, "response");
                break;

            case rasTxStateRipSent:
            {
                int timeLeft = (int)(Rv64Multiply((RvInt64)tx->ripStopTime, 1000) - Rv64Divide(RvTimestampGet(), RV_TIME64_NSECPERMSEC));
                if (timeLeft > 0)
                {
                    /* Let's send a RIP retransmission after calculating the delay */
                    status = rasSendRIP(ras, tx, timeLeft, RV_FALSE);
                }
                else
                    status = RV_ERROR_UNKNOWN;
                break;
            }

            default:
                /* Do nothing - retransmission of something that the application didn't
                   Reply to yet */
                RvLogDebug(&ras->log,
                    (&ras->log, "rasHandleRequest: Retrasmission ignored for transaction 0x%d", tx));
        }

        emaUnlock((EMAElement)tx);
    }

    return status;
}


/************************************************************************
 * rasSendConfirmMessage
 * purpose: Sends a confirm response on an incoming RAS request
 * input  : ras             - RAS module to use
 *          tx              - Incoming transaction
 * output : none
 * return : If an error occurs, the function returns a negative value.
 *          If no error occurs, the function returns a non-negative value.
 ************************************************************************/
int rasSendConfirmMessage(
    IN rasModule*   ras,
    IN rasInTx*     tx)
{
    int status = RV_ERROR_UNKNOWN;

    /* Lock the transaction before dealing with it */
    if(emaLock((EMAElement)tx))
    {
        status = rasSendResponse(ras, tx, cmRASTrStageConfirm, -1, RV_TRUE);

        /* Unlock and release the transaction when we're done */
        emaUnlock((EMAElement)tx);
    }

    return status;
}


/************************************************************************
 * rasSendRejectMessage
 * purpose: Sends a reject response on an incoming RAS request
 * input  : ras             - RAS module to use
 *          tx              - Incoming transaction
 *          reason          - The reject reason to use
 * output : none
 * return : If an error occurs, the function returns a negative value.
 *          If no error occurs, the function returns a non-negative value.
 ************************************************************************/
int rasSendRejectMessage(
    IN rasModule*   ras,
    IN rasInTx*     tx,
    IN cmRASReason  reason)
{
    int status = RV_ERROR_UNKNOWN;

    /* Lock the transaction before dealing with it */
    if(emaLock((EMAElement)tx))
    {
        if (reason == cmRASReasonUnknownMessageResponse)
        {
            RvPvtNodeId nodeId;

            /* Create an XRS message */
            __pvtBuildByFieldIds(nodeId, ras->hVal, tx->txProperty,
                {_q931(response) _q931(unknownMessageResponse) LAST_TOKEN}, 0, NULL);
            tx->responseSet = rasRejectSet;
        }
        else
        {
            /* Set the reject reason of this message */
            status = rasSetParam(ras, (HRAS)tx, cmRASTrStageReject, cmRASParamRejectReason, 0, reason, NULL);
        }

        status = rasSendResponse(ras, tx, cmRASTrStageReject, -1, RV_TRUE);

        /* Unlock and release the transaction when we're done */
        emaUnlock((EMAElement)tx);
    }

    return status;
}


/************************************************************************
 * rasSendRIP
 * purpose: Sends a RIP response on an incoming RAS request
 * input  : ras     - RAS module to use
 *          tx      - Incoming transaction
 *          delay   - Delay for RIP message in milliseconds
 *          updateStopTime  - Indicate if we're updating the stop time
 *                            and increasing the transaction's time or not
 * output : none
 * return : If an error occurs, the function returns a negative value.
 *          If no error occurs, the function returns a non-negative value.
 ************************************************************************/
int rasSendRIP(
    IN rasModule*   ras,
    IN rasInTx*     tx,
    IN int          delay,
    IN RvBool       updateStopTime)
{
    int status, nodeId, progressNodeId;

    /* Make sure delay is within range */
    if ((delay < 1) || (delay > 65535))
    {
        RvLogError(&ras->log,
            (&ras->log, "rasSendRIP: Delay %d out of range for tx=0x%p (1..65535)", delay, tx));
        return RV_ERROR_UNKNOWN;
    }

    /* Build the RIP message */
    nodeId = pvtAddRoot(ras->hVal, ras->synMessage, 0, NULL);
    if (nodeId < 0) return nodeId;
    __pvtBuildByFieldIds(status, ras->hVal, nodeId, {_q931(requestInProgress) _q931(delay) LAST_TOKEN}, delay, NULL);
    if (status < 0)
    {
        pvtDelete(ras->hVal, nodeId);
        return status;
    }

    /* Lock the transaction before dealing with it */
    if(emaLock((EMAElement)tx))
    {
        /* Link the RIP message to the transaction's database */
        progressNodeId = pvtAdd(ras->hVal, tx->txProperty, __q931(progress), 0, NULL, NULL);
        status = pvtMoveTree(ras->hVal, progressNodeId, nodeId);
        if (status < 0)
            pvtDelete(ras->hVal, nodeId);

        /* Send this message */
        if (status >= 0)
            status = rasSendResponse(ras, tx, cmRASTrStageConfirm, progressNodeId, RV_FALSE);

        if (status >= 0)
        {
            tx->state = rasTxStateRipSent;

            if (updateStopTime)
            {
                /* Recalculate the time this transaction will timeout */
                tx->stopTime += delay;
                tx->ripStopTime = (RvInt32)Rv64Divide(RvTimestampGet(), RV_TIME64_NSECPERSEC) + 
                                  ((delay + 999) / 1000); /* Our timeouts for the RAS transactions are calculated in seconds and not milliseconds... */
            }
        }

        /* Unlock and release the transaction when we're done */
        emaUnlock((EMAElement)tx);
    }

    return status;
}


/************************************************************************
 * rasCloseInTx
 * purpose: Close an incoming transaction
 *          This won't actually free resources, only mark the transaction
 *          as a possibility for removal in the garbage collection.
 * input  : ras             - RAS module to use
 *          tx              - Incoming transaction to close
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int rasCloseInTx(
    IN rasModule*       ras,
    IN rasInTx*         tx)
{
    int nodeId = -1;
    void* hMsgContext = NULL;

    RvLockGet(&ras->lockGarbage);
    if(emaLock((EMAElement)tx))
    {
        /* Set garbage collection list to match the required order */
        if (ras->lastTx != NULL) ras->lastTx->next = tx;
        ras->lastTx = tx;
        if (ras->firstTx == NULL) ras->firstTx = tx;

        nodeId = tx->txProperty;
        hMsgContext = tx->hMsgContext;

        emaUnlock((EMAElement)tx);
    }
    RvLockRelease(&ras->lockGarbage);

    /* Free some nodes in the PVT db */
    if (nodeId >= 0)
        pvtDelete(ras->hVal, nodeId);

    /* Dispose of the message context for this transaction if we've got any */
    if (hMsgContext != NULL)
        ras->cmiEvRASReleaseMessageContext(hMsgContext);

    return 0;
}



#ifdef __cplusplus
}
#endif


⌨️ 快捷键说明

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