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

📄 transutil.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
                (&transGlobals->hLog,
                    "cmEvTransBadMessage(hsSession = %d(%p), haSession=%p, type=%d,outgoing=RV_TRUE)",
                    emaGetIndex((EMAElement)session), session, haTransSession, type));

            numOfLocks = emaPrepareForCallback((EMAElement)session);
            transGlobals->sessionEventHandlers.cmEvTransBadMessage(
                        (HSTRANSSESSION) session,
                        haTransSession,
                        type,
                        &buffer[headersSize],
                        encSize,
                        RV_TRUE);
            emaReturnFromCallback((EMAElement)session, numOfLocks);
        }

        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "transEncodeMessage Failed on encoding"));
        return cmTransErr;
    }
    else
    if (encTransRes == cmTransIgnoreMessage)
    {
        RvLogInfo(&transGlobals->hLog,
            (&transGlobals->hLog, "transEncodeMessage Mesage rejected by user"));
        return cmTransIgnoreMessage;
    }

    /* print just for tunneled messages here */
    if (!host)
        printHexBuff(&buffer[headersSize], encSize, &transGlobals->hTPKTCHAN);
    return cmTransOK;
 }

/**************************************************************************************
 * addSessionToPendingList
 *
 * Purpose: Add a session to the list of sessions that were unable to send a message
 *          due to lack of rpool resources. Such sessions should be notified when
 *          resources become available again.
 * Input:   transGlobals - The global data of the transport module.
 *          session      - The session which failed to send the message.
 *
 * Output:  None.
 *
 **************************************************************************************/
void addSessionToPendingList(IN cmTransGlobals *transGlobals,
                             IN cmTransSession *session)
{
    cmTransSession *oldFirstSession;

    RvMutexLock(&transGlobals->lockSessionsList);

    oldFirstSession                 = transGlobals->pendingList;
    session->nextPending            = oldFirstSession;
    session->prevPending            = NULL;
    if (oldFirstSession)
        oldFirstSession->prevPending    = session;
    transGlobals->pendingList       = session;

    RvMutexUnlock(&transGlobals->lockSessionsList);

}

/**************************************************************************************
 * removeSessionFromPendingList
 *
 * Purpose: Remove a session from the list of sessions that were unable to send a message
 *          due to lack of rpool resources. Such sessions are removed when notified that
 *          resources become available again.
 * Input:   transGlobals - The global data of the transport module.
 *          session      - The session which failed to send the message.
 *
 * Output:  None.
 *
 **************************************************************************************/
void removeSessionFromPendingList(
    IN cmTransGlobals *transGlobals,
    IN cmTransSession *session)
{
    cmTransSession *previousSession;

    RvMutexLock(&transGlobals->lockSessionsList);

    previousSession = session->prevPending;

    /* disconnect the session from the pending list */
    if (previousSession)
        previousSession->nextPending    = session->nextPending;
    if (session->nextPending)
        session->nextPending->prevPending = previousSession;

    /* update the list header if session was the head of the list */
    if (transGlobals->pendingList == session)
        transGlobals->pendingList = session->nextPending;

    RvMutexUnlock(&transGlobals->lockSessionsList);
}

/**************************************************************************************
 * notifyPendingSessions
 *
 * Purpose: This routine notifies that space is free for pending messages.
 * Input:   transGlobals - The global data of the transport module.
 *          numOfSession - The number of sessions that can be released from the list.
 *
 * Output:  None.
 *
 **************************************************************************************/
void notifyPendingSessions(cmTransGlobals *transGlobals, int numOfSessions)
{
    cmTransSession  *session = transGlobals->pendingList;
    int i;

    for (i=0; (i<numOfSessions && (session)); i++,session=session->nextPending)
    {
        if (transGlobals->sessionEventHandlers.cmEvTransWrite)
        {
            int numOfLocks;
            HATRANSSESSION haTransSession = (HATRANSSESSION)emaGetApplicationHandle((EMAElement)session);
            RvLogInfo(&transGlobals->hLog,
                (&transGlobals->hLog, "cmEvTransWrite hsTransSession=%d(%x) haTransSession=%x",
                    emaGetIndex((EMAElement)session), session,  haTransSession));

            numOfLocks = emaPrepareForCallback((EMAElement)session);
            transGlobals->sessionEventHandlers.cmEvTransWrite((HSTRANSSESSION) session,
                                                              haTransSession);
            emaReturnFromCallback((EMAElement)session, numOfLocks);

            removeSessionFromPendingList(transGlobals, session);
        }
    }
}

/**************************************************************************************
 * saveMessageToPool
 *
 * Purpose: This routine gets an encoded message and saves it, until it can send it.
 * Input:   transGlobals - The global data of the transport module.
 *          element      - The session which wants to send the message.
 *          buffer       - The encoded message.
 *          encMsgSize   - Its size.
 *          isTunneled   - RV_TRUE: save to the tunneled message queue,
 *                         RV_FALSE: to the sending message queue
 *          addToTop     - RV_TRUE: Add the message to the start of the queue
 *                         RV_FALSE: Add it at the end.
 *          CRV          - The CRV of the call on which behalf the message is sent
 *                         (used for annex E session ID field).
 *
 * Output:  None.
 *
 **************************************************************************************/
HRPOOLELEM saveMessageToPool(cmTransGlobals *transGlobals,
                            void            *element,
                            RvUint8         *buffer,
                            int             encMsgSize,
                            RvBool          isTunneled,
                            RvBool          addToTop,
                            RvUint16        CRV)
{
    HRPOOLELEM     newMsg;
    HRPOOLELEM     firstMsg = NULL;
    HRPOOLELEM     lastMsg = NULL;
    cmTransHost    *host    = (cmTransHost *)element;
    cmTransSession *session = (cmTransSession *)element;

    /* clear the admin header & TPKT header */
    memset(buffer, 0, MSG_HEADER_SIZE+TPKT_HEADER_SIZE);

    /* lock the rpool */
    RvLockGet(&transGlobals->lockHash);

    /* get rpool buffer and copy the encoded message to it */
    newMsg  = rpoolAllocCopyExternal(transGlobals->messagesRPool,
                                     buffer,
                                     encMsgSize+MSG_HEADER_SIZE+TPKT_HEADER_SIZE);
    if (newMsg)
    {
        /* determine which queue of messages we work on (tunneled, or to be sent)*/
        if (isTunneled)
        {
            firstMsg = session->firstMessage;
            lastMsg  = session->lastMessage;
        }
        else
        {
            firstMsg = host->firstMessage;
            lastMsg  = host->lastMessage;
        }

        /* update the pointer from the element to the saved messages */
        if (!firstMsg)
        {
            firstMsg = newMsg;
            lastMsg  = newMsg;
        }

        if (addToTop)
        {
            if (firstMsg != newMsg)
            {
                rpoolCopyFromExternal(transGlobals->messagesRPool,
                                      newMsg,
                                      (void *)&firstMsg,
                                      0,
                                      MSG_HEADER_SIZE);
                firstMsg = newMsg;
            }
        }
        else
        {
            /* update the last saved message to point to the new message
               and make the new message to be the last message */
            if (lastMsg != newMsg)
            {
                    rpoolCopyFromExternal(transGlobals->messagesRPool,
                                          lastMsg,
                                          (void *)&newMsg,
                                          0,
                                          MSG_HEADER_SIZE);
                lastMsg = newMsg;
            }
        }

        /* update the CRV on the TPKT header */
        rpoolCopyFromExternal(transGlobals->messagesRPool,
                              newMsg,
                              (void *)&CRV,
                              MSG_HEADER_SIZE,
                              sizeof(CRV));

        /* Update the last message pointer in the appropriate element */
        if (isTunneled)
        {
            session->firstMessage = firstMsg;
            session->lastMessage  = lastMsg;
        }
        else
        {
            host->firstMessage = firstMsg;
            host->lastMessage  = lastMsg;
        }


        {
            RvInt32 poolSize, usageSize, allocatedSize;

            if (rpoolStatistics(transGlobals->messagesRPool,
                                &poolSize,
                                &usageSize,
                                &allocatedSize))
            {
                RvLogInfo(&transGlobals->hLog, (&transGlobals->hLog,
                        "saveMessageToPool[isTunneled=%d] statistics: max=%d, usage=%d, allocated=%d",
                        isTunneled, poolSize, usageSize, allocatedSize));
            }
        }

        RvLogDebug(&transGlobals->hLog, (&transGlobals->hLog,
            "saveMessageToPool[isTunneled=%d] new = %x", isTunneled, newMsg));

        /* update num of messages kept in rpool for sending */
        transGlobals->curUsedNumOfMessagesInRpool++;
        if (transGlobals->curUsedNumOfMessagesInRpool > transGlobals->maxUsedNumOfMessagesInRpool)
            transGlobals->maxUsedNumOfMessagesInRpool++;

        /* unlock the rpool */
        RvLockRelease(&transGlobals->lockHash);
    }
    else
    {
        /* NO BUFFERS */

        {
            RvInt32 poolSize, usageSize, allocatedSize;

            if (rpoolStatistics(transGlobals->messagesRPool,
                                &poolSize,
                                &usageSize,
                                &allocatedSize))
            {
                RvLogInfo(&transGlobals->hLog, (&transGlobals->hLog,
                        "saveMessageToPool (no buffers) statistics: max=%d, usage=%d, allocated=%d",
                        poolSize, usageSize, allocatedSize));
            }
        }

        /* unlock the rpool */
        RvLockRelease(&transGlobals->lockHash);

        RvLogWarning(&transGlobals->hLog, (&transGlobals->hLog,
            "saveMessageToPool has no buffers"));
        return NULL;
    }
    return newMsg;
}


/**************************************************************************************
 * extractMessageFromPool
 *
 * Purpose: This routine removes an encoded message from the head of the host list.
 *          The messages extracted here are tunneled messages.
 * Input:   transGlobals - The global data of the transport module.
 *          element      - The host or session which wants to send the message.
 *          isTunneled   -  TRUE: remove from the tunneled message queue,
 *                          FALSE: remove from the sending message queue
 *
 * Output:  None.
 *
 * Return Value: next message.
 *
 **************************************************************************************/
HRPOOLELEM extractMessageFromPool(
                             cmTransGlobals *transGlobals,
                             void           *element,
                             RvBool         isTunneled)
{
     HRPOOLELEM     nextMsg;
     HRPOOLELEM     firstMsg;
     cmTransHost    *host       = (cmTransHost *)element;
     cmTransSession *session    = (cmTransSession *)element;
     RvInt32        poolSize, allocatedSize;

    /* determine which queue of messages we work on (tunneled, or to be sent)*/
    if (isTunneled)
        firstMsg = session->firstMessage;
    else
        firstMsg = host->firstMessage;

⌨️ 快捷键说明

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