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

📄 rasout.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Take it from configuration - the gatekeeper's address */

        srcNodeId = ras->gatekeeperRASAddress;
        if (ras->gatekeeperRASAddress < 0)
            __pvtGetNodeIdByFieldIds(srcNodeId, ras->hVal, ras->confNode, {_q931(manualDiscovery) _q931(defaultGatekeeper) LAST_TOKEN});

        /* Save the GK RAS address*/
        if ((ras->gatekeeperRASAddress < 0) && (srcNodeId >= 0))
        {
            ras->gatekeeperRASAddress = pvtAddRoot(ras->hVal, NULL, 0, NULL);
            pvtSetTree(ras->hVal,ras->gatekeeperRASAddress,ras->hVal,srcNodeId);
        }
        status=0;
        if (srcNodeId>=0)
            status = cmVtToTA(ras->hVal, srcNodeId, &tx->destAddress);
        else
            memset(&(tx->destAddress),0,sizeof(cmTransportAddress));
    }
    else if (destAddress != NULL)
    {
        /* Get the address the user gave us */
        tx->destAddress = *destAddress;
    }

    /* Build the default request message */
    if (status >= 0)
    {
        requestNode = pvtAdd(ras->hVal, tx->txProperty, __q931(request), 0, NULL, NULL);
        status = pvtSetTree(ras->hVal, requestNode, ras->hVal, ras->defaultMessages[transaction][cmRASTrStageRequest]);
    }

    /* Calculate the number of retries for this transaction */
    tx->retryCount = rasCfgGetRetries(ras);

    if (status < 0)
    {
        pvtDelete(ras->hVal, tx->txProperty);
        emaDelete(tx);
        return NULL;
    }
    return tx;
}


/************************************************************************
 * rasSendRequestMessage
 * purpose: Send an outgoing request message
 * input  : ras             - RAS module to use
 *          tx              - Outgoing transaction to send
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int rasSendRequestMessage(
    IN rasModule*       ras,
    IN rasOutTx*        tx)
{
    RvUint32    reqSeqNum;
    int         nodeId, reqNodeId;
    int         status = 0;

    /* Set the sequence number of the transaction */
    RvLockGet(&ras->lockOutHash);
    if (ras->requestSeqNum == 65535)
        ras->requestSeqNum = 2;
    else
        ras->requestSeqNum++;
    reqSeqNum = ras->requestSeqNum;

    /* Update the outgoing hash table with this transaction */
    if (tx->hashValue != NULL)
        hashDelete(ras->outHash, tx->hashValue);
    tx->hashValue = hashAdd(ras->outHash, &reqSeqNum, &tx, RV_TRUE);
    if (tx->hashValue == NULL)
    {
        RvLogError(&ras->log,
            (&ras->log, "rasSendRequestMessage: Cannot insert to hash 0x%p (requestSeqNum=%d)",
                 tx, reqSeqNum));
        status = RV_ERROR_UNKNOWN;
    }

    /* Lock the transaction and then unlock the hash */
    if (status >= 0)
        if(!emaLock((EMAElement)tx))
            status = RV_ERROR_UNKNOWN;
    RvLockRelease(&ras->lockOutHash);
    if (status < 0)
        return status;

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

    /* Get the request message */
    reqNodeId = pvtGetChild(ras->hVal, tx->txProperty, __q931(request), NULL);
    if (reqNodeId < 0) status = reqNodeId;

    /* Set the sequence number inside the outgoing request message */
    __pvtBuildByFieldIds(nodeId, ras->hVal, reqNodeId, {_anyField _q931(requestSeqNum) LAST_TOKEN}, (RvInt32)reqSeqNum, NULL);

    /* Mark transaction before using any of the callbacks */

    if (status >= 0)
        status = rasEncodeAndSend(ras, (HRAS)tx, cmRASTrStageRequest, reqNodeId, tx->isMulticast, &tx->destAddress, RV_TRUE, &tx->encodedMsg);

    if (status >= 0)
    {
        /* No one closed this transaction - set the timer and finish with it */

        switch (tx->transactionType)
        {
            case cmRASNonStandard:
                /* Non-associated transaction */
                tx->state = rasTxStateIdle;
                tx->retryCount = 0;
                break;

            case cmRASUnsolicitedIRR:
            {
                /* Check if this IRR is waiting for a reply of some kind */
                RvInt32 needResponse;
                __pvtGetByFieldIds(nodeId, ras->hVal, reqNodeId, {_anyField _q931(needResponse) LAST_TOKEN}, NULL, &needResponse, NULL);
                if (!needResponse)
                {
                    /* We're not looking for a response - change state and end switch */
                    tx->state = rasTxStateIdle;
                    tx->retryCount = 0;
                    break;
                }

                /* If we got here, then we should wait for the
                   response as the rest of the messages: */
            }

            default:
            {
                RvInt timeout;

                /* We'll be waiting for a reply... */
                tx->state = rasTxStateRequestSent;
		if(tx->transactionType == cmRASAdmission)
			timeout = 2* 1000;
		else
                /* Set the timer for retries */
                timeout = rasCfgGetTimeout(ras) * 1000;
                tx->timer = RvH323TimerStartPeriodic(ras->timers, rasTimeoutEvent, tx, timeout);
            }
        }
    }

    emaUnlock((EMAElement)tx);

    return status;
}


/************************************************************************
 * rasDummyRequest
 * purpose: Handle incoming unsolicited IRRs as responses
 * input  : ras             - RAS module to use
 *          tx              - Outgoing transaction to send
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int rasDummyRequest(
    IN rasModule*       ras,
    IN rasOutTx*        tx)
{
    /* We only act as if a message was sent so we'll be waiting for responses */

    /* Make sure it's an unsolicited IRR transaction */
    if ((tx->transactionType != cmRASUnsolicitedIRR) || (tx->hsCall == NULL))
    {
        RvLogError(&ras->log,
            (&ras->log, "rasDummyRequest: Not an unsolicited IRR transaction (tx=0x%p)", tx));
        return RV_ERROR_UNKNOWN;
    }

    if(emaLock((EMAElement)tx))
    {
        tx->state = rasTxStateRequestSent;
        emaUnlock((EMAElement)tx);
    }

    /* Make sure we've got this handle in the CAT */
    return catSetUnsolicitedIRR(ras->hCat, cmiGetCatForCall(tx->hsCall), (HRAS)tx);
}


/************************************************************************
 * rasHandleReply
 * purpose: Handle a reply of an outgoing request message
 * input  : ras             - RAS module to use
 *          srcAddress      - Address of the sender
 *          messageBuf      - The message buffer to send
 *          messageLength   - The length of the message in bytes
 *          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
 *          seqNum          - requestSeqNum field value of the message
 * 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 rasHandleReply(
    IN  rasModule*      ras,
    IN  cmRASTransport* srcAddress,
    IN  RvUint8*        messageBuf,
    IN  RvUint32        messageLength,
    IN  int             messageNodeId,
    IN  rasMessages     messageType,
    IN  RvUint32        seqNum,
    OUT void**          hMsgContext)
{
    rasOutTx*       tx;
    void*           hashValue;
    int             status = 0;

    /* Lock hash to find the transaction */
    RvLockGet(&ras->lockOutHash);

    /* Look for this transaction */
    hashValue = hashGetElement(ras->outHash, hashFind(ras->outHash, &seqNum));
    if (hashValue != NULL)
        tx = *((rasOutTx **)hashValue);
    else
        tx = NULL;
    if (tx == NULL)
    {
        RvLogWarning(&ras->log,
            (&ras->log, "rasHandleReply: Transaction not found for seqNum=%d", seqNum));
        if (messageNodeId >= 0)
            pvtDelete(ras->hVal, messageNodeId);
        RvLockRelease(&ras->lockOutHash);
        return RV_ERROR_UNKNOWN;
    }

    /* Lock the transaction and unlock the hash table */
    emaLock((EMAElement)tx);
    RvLockRelease(&ras->lockOutHash);

    /* Make sure we're still waiting for a reply of some kind */
    if (!((tx->state == rasTxStateRequestSent) || (tx->state == rasTxStateRipReceived) ||
          ((tx->isMulticast == RV_TRUE) && (tx->state == rasTxStateReplyReceived))))
    {
        RvLogWarning(&ras->log,
            (&ras->log, "rasHandleReply: Transaction 0x%p not waiting for replies. Reply is discarded", tx));
        if (messageNodeId >= 0)
            pvtDelete(ras->hVal, messageNodeId);
        status = RV_ERROR_UNKNOWN;
    }

    /* Make sure this message belongs to the transaction */
    if ((status >= 0) && (tx->transactionType != rasMessageInfo[messageType].transaction))
    {
        switch (messageType)
        {
            case rasMsgUnknownMessageResponse:
            case rasMsgRequestInProgress:
                /* We're fine - let these messages continue */
                break;
            default:
                RvLogWarning(&ras->log,
                    (&ras->log, "rasHandleReply: Reply (%d) doesn't match this transaction type (%d)", messageType, tx->transactionType));
                status = RV_ERROR_UNKNOWN;
        }
    }

    if ((messageNodeId < 0) && (status >= 0))
    {
        /* We're in business - decode the whole message if we have to */
        rasMessages newType;
        RvUint32    newSeqNum;

        status =
            rasDecodeAndRecv(ras, messageBuf, messageLength, RV_FALSE, srcAddress,
                             &messageNodeId, &newType, &newSeqNum, hMsgContext);

        /* Make sure the application didn't change the sequence number or type of message */
        if ((status >= 0) && ((newSeqNum != seqNum) || (messageType != newType)))
        {

⌨️ 快捷键说明

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