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

📄 rasout.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
            /* Reroute the message to check it again... */
            emaUnlock((EMAElement)tx);
            return rasRouteMessage(ras, rasChanUnicast, srcAddress, messageBuf, messageLength, messageNodeId, newType, newSeqNum, hMsgContext);
        }
    }

    if (status < 0)
    {
        /* Probably couldn't decode this message... */
        if (messageNodeId >= 0)
            pvtDelete(ras->hVal, messageNodeId);
        emaUnlock((EMAElement)tx);
        return status;
    }

    if (messageType == rasMsgRequestInProgress)
    {
        /* We've got a RIP - handle it differently */
        status = rasHandleIncomingRIP(ras, tx, messageNodeId);
        emaUnlock((EMAElement)tx);
        return status;
    }

    /* We found the transaction - start handling it properly */
    /* - No need to unlock the element - rasHandleTxResponse does that automatically */
    return rasHandleTxResponse(ras, tx, messageNodeId, messageType, hMsgContext);
}


/************************************************************************
 * rasHandleTxResponse
 * purpose: Handle a reply of an outgoing request message, when we already
 *          know the exact transaction. This function is used internally
 *          by rasHandleReply() and when we've got an unsolicited IRR on
 *          a dummy request.
 *          This function doesn't lock the transaction when handling it.
 *          It assumes that the transaction is already locked from somewhere
 *          else. It will unlock the transaction when finished.
 * input  : ras             - RAS module to use
 *          tx              - Transaction we're dealing with
 *          messageNodeId   - Node ID of message root. If negative, then
 *                            message is decoded from given buffer and hook
 *                            is called
 *          messageType     - Message type of the reply
 * output : hMsgContext     - Incoming message context. Used mostly by security
 *                            If the returned value is different than NULL,
 *                            then the message context is not used by the
 *                            transaction and should be released
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int rasHandleTxResponse(
    IN  rasModule*      ras,
    IN  rasOutTx*       tx,
    IN  int             messageNodeId,
    IN  rasMessages     messageType,
    OUT void**          hMsgContext)
{
    HAPPRAS         haRas;
    int             rootId;
    int             status;
    cmRASTrStage    stage;

    if (rasMessageInfo[messageType].msgType == rasTxMsgConfirm)
        stage = cmRASTrStageConfirm;
    else
        stage = cmRASTrStageReject;

    /* Make sure to notify the application of an incoming RAS message */
    if (ras->evMessages.cmEvRasMessageReceive != NULL)
    {
        /* An internal callback - no log for this one */
        ras->evMessages.cmEvRasMessageReceive(messageNodeId, stage, (HRAS)tx, ras->evMessages.hAppRasMsg);
    }

    /* Add the decoded message to the transaction's DB */
    rootId = pvtAdd(ras->hVal, tx->txProperty, __q931(response), 0, NULL, NULL);
    status = pvtMoveTree(ras->hVal, rootId, messageNodeId);
    messageNodeId = rootId;

    /* Make sure timer is released */
    RvH323TimerCancel(ras->timers, &tx->timer);

    /* Update the transaction's state only if it's not multicast.
       For multicast transactions we want to receive any incoming message */
    if ((status >= 0) && (!tx->isMulticast))
        tx->state = rasTxStateReplyReceived;

    /* Mark the transaction before the callback and unlock it */
    emaMark((EMAElement)tx);

    emaUnlock((EMAElement)tx);

    if (status >= 0)
    {
        haRas = (HAPPRAS)emaGetApplicationHandle((EMAElement)tx);

        /* If we get GCF then save the GK RAS address*/
        if (messageType == rasMsgGatekeeperConfirm)
        {
            int srcNodeId;
            if (ras->gatekeeperRASAddress < 0)
                ras->gatekeeperRASAddress = pvtAddRoot(ras->hVal, NULL, 0, NULL);
            __pvtGetNodeIdByFieldIds(srcNodeId, ras->hVal, messageNodeId, {_anyField _q931(rasAddress) LAST_TOKEN});
            pvtSetTree(ras->hVal, ras->gatekeeperRASAddress, ras->hVal, srcNodeId);
        }

        /* Make sure we update the registration information if we have to */
        if (messageType == rasMsgRegistrationConfirm)
        {
            rasUpdateRegInfo(ras, messageNodeId);

            /* Let's get the GK address - just in case... */
            if (ras->gatekeeperRASAddress < 0)
                ras->gatekeeperRASAddress = pvtAddRoot(ras->hVal, ((cmElem*)(ras->app))->hAddrSyn, 0, NULL);
            cmTAToVt(ras->hVal, ras->gatekeeperRASAddress, &tx->destAddress);
        }
        if (messageType == rasMsgUnregistrationConfirm)
        {
            /* Get the original request */
            int requestId = pvtGetChild(ras->hVal, tx->txProperty, __q931(request), NULL);
            int nodeId;
            /* now see if it was a partial unregistration */
            __pvtGetNodeIdByFieldIds(nodeId, ras->hVal, requestId , {_q931(unregistrationRequest) _q931(endpointAlias) LAST_TOKEN});

            if(nodeId<0)
                /* it was a full unregistration */
                rasUpdateRegInfo(ras, -1);
            else
                /* just remove these aliases */
                rasUpdatePartUnreg(ras, requestId);
        }
        /* Check if we have an automatic RAS callback - if we do, this will
           override any manual RAS callback... */

        /* Automatic RAS callback */
        if (tx->evResponse != NULL)
        {
            /* We should overide the manual RAS callbacks - the automatic RAS should decide
               if it should be called */

            /* Associate message context with transaction */
            tx->hMsgContext = *hMsgContext;
            *hMsgContext = NULL;

            /* Callback... */
            if ((rasMessageInfo[messageType].msgType == rasTxMsgConfirm) && (ras->evAutoRas.cmEvAutoRASConfirm != NULL))
            {
                cmiCBEnter(ras->app, "cmEvAutoRASConfirm(hsRas=0x%p)", tx);
                ras->evAutoRas.cmEvAutoRASConfirm((HRAS)tx);
                cmiCBExit(ras->app, "cmEvAutoRASConfirm(hsRas=0x%p)", tx);
            }
            else if ((rasMessageInfo[messageType].msgType == rasTxMsgReject) && (ras->evAutoRas.cmEvAutoRASReject != NULL))
            {
                /* Find out the reject reason and then set the callback */
                RvInt32 reason;
                if (messageType == rasMsgUnknownMessageResponse)
                    reason = cmRASReasonUnknownMessageResponse; /* Reason is XRS */
                else
                {
                    /* Get the reason field from the reject message */
                    status = rasGetParam(ras, (HRAS)tx, cmRASTrStageReject, cmRASParamRejectReason, 0, &reason, NULL);
                }
                cmiCBEnter(ras->app, "cmEvAutoRasReject(hsRas=0x%p)", tx);
                ras->evAutoRas.cmEvAutoRASReject((HRAS)tx, (cmRASReason)reason);
                cmiCBExit(ras->app, "cmEvAutoRasReject(hsRas=0x%p)", tx);
            }

            if (!emaWasDeleted((EMAElement)tx))
                tx->evResponse(haRas, (HRAS)tx, stage);
        }
        else
        {
            /* Manual RAS callbacks */

            /* Start with the callbacks */
            if ((rasMessageInfo[messageType].msgType == rasTxMsgConfirm) && (ras->evApp.cmEvRASConfirm != NULL))
            {
                /* Associate message context with transaction */
                tx->hMsgContext = *hMsgContext;
                *hMsgContext = NULL;

                /* xCF message */
                cmiCBEnter(ras->app, "cmEvRASConfirm(haRas=0x%p,hsRas=0x%p)", haRas, tx);
                ras->evApp.cmEvRASConfirm(haRas, (HRAS)tx);
                cmiCBExit(ras->app, "cmEvRASConfirm(haRas=0x%p,hsRas=0x%p)", haRas, tx);
            }
            else if ((rasMessageInfo[messageType].msgType == rasTxMsgReject) && (ras->evApp.cmEvRASReject != NULL))
            {
                /* xRJ message */

                /* Find out the reject reason and then set the callback */
                RvInt32 reason;

                if (messageType == rasMsgUnknownMessageResponse)
                    reason = cmRASReasonUnknownMessageResponse; /* Reason is XRS */
                else
                {
                    /* Get the reason field from the reject message */
                    status = rasGetParam(ras, (HRAS)tx, cmRASTrStageReject, cmRASParamRejectReason, 0, &reason, NULL);
                }

                /* Associate message context with transaction */
                tx->hMsgContext = *hMsgContext;
                *hMsgContext = NULL;

                /* Make sure we notify the application with a callback... */
                cmiCBEnter(ras->app, "cmEvRasReject(haRas=0x%p,hsRas=0x%p)", haRas, tx);
                ras->evApp.cmEvRASReject(haRas, (HRAS)tx, (cmRASReason)reason);
                cmiCBExit(ras->app, "cmEvRasReject(haRas=0x%p,hsRas=0x%p)", haRas, tx);
            }
        }
    }

    /* Release the transaction and we're done */
    emaRelease((EMAElement)tx);

    return status;
}


/************************************************************************
 * rasCloseOutTx
 * purpose: Close an outgoing transaction
 * input  : ras             - RAS module to use
 *          tx              - Outgoing transaction to close
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int rasCloseOutTx(
    IN rasModule*       ras,
    IN rasOutTx*        tx)
{
    int     nodeId;
    void*   hMsgContext;

    /* Lock the hash table first */
    RvLockGet(&ras->lockOutHash);

    /* Lock the transaction itself and mark it - we'll delete it before unlocking it... */
    if(emaLock((EMAElement)tx))
    {
        /* Delete the hash entry */
        if (tx->hashValue != NULL)
            hashDelete(ras->outHash, tx->hashValue);

        /* Unlock the hash table before killing the transaction */
        RvLockRelease(&ras->lockOutHash);

        /* Get all the handle we need to remove after unlocking */
        nodeId = tx->txProperty;
        hMsgContext = tx->hMsgContext;

        /* Kill the timer if there is one - before unlocking... */
        RvH323TimerCancel(ras->timers, &tx->timer);

        /* Remove RPOOL element */
        if (tx->encodedMsg != NULL)
            rpoolFree(ras->messages, tx->encodedMsg);

        /* Delete, Unlock and Release */
        emaDelete((EMAElement)tx);
        emaUnlock((EMAElement)tx);

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

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

    return 0;
}




#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

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