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

📄 transutil.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
 *
 **************************************************************************************/
void transSessionClose(cmTransSession *session)
{
    cmTransGlobals *transGlobals;
    HRPOOLELEM     msg;

    /* retrieve the transport module global area */
    transGlobals = (cmTransGlobals *)emaGetUserData((EMAElement)session);

    /* delete session's zero-timer if exist */
    RvH323TimerCancel(transGlobals->hTimers, &session->zeroTimer);

    /* remove it from the pending list, if it's there */
    removeSessionFromPendingList(transGlobals, (cmTransSession *)session);

    /* close the H.245 connection of the session */
    if (session->H245Connection)
        closeHostInternal((HSTRANSHOST)session->H245Connection, RV_TRUE);

    /* Release all nodes held on the session */
    if (session->h450Element >= 0)
        pvtDelete(transGlobals->hPvt, session->h450Element);

    if (session->h450AlertElement >= 0)
        pvtDelete(transGlobals->hPvt, session->h450AlertElement);

    if (session->annexMElement >= 0)
        pvtDelete(transGlobals->hPvt, session->annexMElement);

    if (session->annexLElement >= 0)
        pvtDelete(transGlobals->hPvt, session->annexLElement);

    /* remove session from host list of sessions */
    {
        cmTransHost    *host;

        /* update, if necessary, the list header for the host */
        if (session->Q931Connection)
        {
            host = session->Q931Connection;

            /* remove the session from the host */
            RvMutexLock(&transGlobals->lockSessionsList);
            if (host->firstSession == session)
                host->firstSession = session->nextSession;
            RvMutexUnlock(&transGlobals->lockSessionsList);

            /* if no more sessions on host, close host, if necessary */
            if (!host->firstSession)
                if ((host->closeOnNoSessions) || (host->remoteCloseOnNoSessions) ||
                    (!host->isMultiplexed) || (!host->remoteIsMultiplexed))
                {
                    closeHostInternal((HSTRANSHOST)host, RV_TRUE);
                }
            session->Q931Connection = NULL;

        }

        if (session->annexEConnection)
        {
            host = session->annexEConnection;

            /* remove the session from the host */
            RvMutexLock(&transGlobals->lockSessionsList);
            if (host->firstSession == session)
                host->firstSession = session->nextSession;
            RvMutexUnlock(&transGlobals->lockSessionsList);

            /* if no more sessions on host, close host, if necessary */
            if (!host->firstSession)
                if ((host->closeOnNoSessions) || (host->remoteCloseOnNoSessions))
                    closeHostInternal((HSTRANSHOST)host, RV_TRUE);

            session->annexEConnection = NULL;
        }

        /* remove it from the list */
        RvMutexLock(&transGlobals->lockSessionsList);
        if (session->nextSession)
            session->nextSession->prevSession = session->prevSession;
        if (session->prevSession)
            session->prevSession->nextSession = session->nextSession;
        RvMutexUnlock(&transGlobals->lockSessionsList);
    }

    /* remove the session from the hash table */
    if (session->hashEntry)
    {
        hashDelete(transGlobals->hHashSessions, session->hashEntry);
        session->hashEntry = NULL;
    }

    /* go over the tunneled messages still stored for the session and free them from the pool */
    msg = session->firstMessage;
    while (msg)
        msg = extractMessageFromPool(transGlobals, session, RV_TRUE);
}


/**************************************************************************************
 * transHostClose
 *
 * Purpose: This routine reports a host close and tells the sessions connected to
 *          it that the connection has ended and releasing all the messages kept for it
 *          in the pool.
 *
 * Input/Output:   hsTransHost      - The host to be deleted.
 *                 killHost         - Should the host be removed from the hash and close
 *                                    its TPKT element or just disconnect from session?
 *
 * Output:  None.
 *
 **************************************************************************************/
void transHostClose(HSTRANSHOST hsTransHost, RvBool killHost)
{
    cmTransHost     *host;
    cmTransGlobals  *transGlobals;
    void            *sess;
    void            *nextSess;
    int             numOfLocks;
    HRPOOLELEM      msg;

    if (!hsTransHost)
        return;

    host = (cmTransHost *)hsTransHost;
    if (!host)
        return;

    /* retrieve the transport module global area */
    transGlobals = (cmTransGlobals *)emaGetUserData((EMAElement)host);

    /* close the hosts tpkt elements */
    if ( (host->h245Listen) && (killHost) )
    {
        tpktClose(host->h245Listen);
        host->h245Listen = NULL;
    }

    if ( (host->hTpkt) && (killHost) )
    {
        tpktClose(host->hTpkt);
        host->hTpkt = NULL;
    }

    /* close the hosts annex E node */
    if ( (host->annexEUsageMode == cmTransUseAnnexE) && (killHost) && (transGlobals->annexECntrl != NULL) )
    {
        annexEStatus eStat = annexECloseNode(transGlobals->annexECntrl,
                                             host->remoteAddress.ip,
                                             host->remoteAddress.port);
        if (eStat != annexEStatusNormal)
        {
            RvLogError(&transGlobals->hLog,
                (&transGlobals->hLog, "failed to close annex E node on host=%x",host));
        }
    }

    RvMutexLock(&transGlobals->lockSessionsList);
    sess = (void *)host->firstSession;
    msg = host->firstMessage;
    RvMutexUnlock(&transGlobals->lockSessionsList);

    RvLogInfo(&transGlobals->hLog,
        (&transGlobals->hLog, "transHostClose(hsTransHost = %d-%x)",
        emaGetIndex((EMAElement)hsTransHost), hsTransHost));

    /* go over the messages still stored for the host and free them from the pool */
    while (msg)
        msg = extractMessageFromPool(transGlobals, host, RV_FALSE);

	RvLockGet(&transGlobals->lockHash);
    if (host->incomingMessage)
    {
        rpoolFree(transGlobals->messagesRPool, host->incomingMessage);
        {
            RvInt32 poolSize, usageSize, allocatedSize;

            if (rpoolStatistics(transGlobals->messagesRPool,
                                &poolSize,
                                &usageSize,
                                &allocatedSize))
            {
                RvLogInfo(&transGlobals->hLog, (&transGlobals->hLog,
                        "rpoolFree[transHostClose] statistics: max=%d, usage=%d, allocated=%d",
                        poolSize, usageSize, allocatedSize));
            }
        }
        host->incomingMessage = NULL;
    }
    RvLockRelease(&transGlobals->lockHash);

    /* go over all the sessions that are connected to this host */

    /* unlock the host so it won't be locked before the sessions */
    numOfLocks = emaPrepareForCallback((EMAElement)host);

    while ((sess != NULL) && (emaLock((EMAElement)sess)))
    {
        /* report to the user that the connection of the session was closed */
        HATRANSSESSION haTransSession;
        cmTransSession *session = (cmTransSession *)sess;
        RvBool         hostReported;
        RvBool         anotherQ931HostExists;


        {
            haTransSession = (HATRANSSESSION)emaGetApplicationHandle((EMAElement)session);

            RvMutexLock(&transGlobals->lockSessionsList);
            nextSess = session->nextSession;
            RvMutexUnlock(&transGlobals->lockSessionsList);

            /* determine whether the closing host was reported to the user, so we need to report its
               closing too */
            hostReported = ( ((session->Q931Connection == host)   && (session->reportedQ931Connect)) ||
                             ((session->annexEConnection == host) && (session->reportedQ931Connect)) ||
                             ((session->H245Connection == host)   && (session->reportedH245Connect)) );

            /* check if it's a Q.931 host and if ther are two (TPKT & annex E) so the closing is due to
               a race between them, and no reporting is needed to the user at this stage */
            anotherQ931HostExists = ( ((session->Q931Connection == host) || (session->annexEConnection == host)) &&
                                      (session->Q931Connection && session->annexEConnection) );

            if ( (transGlobals->sessionEventHandlers.cmEvTransConnectionOnSessionClosed) &&
                 hostReported && (!anotherQ931HostExists))
            {
                /* in case of tunneling report also the close of the H.245 tunneled connection */
                if ( (host->type == cmTransQ931Conn) &&
                     (session->tunnelingState == tunnApproved) &&
                     (session->reportedH245Connect) )
                {
                    int numOfLocks;
                    RvLogInfo(&transGlobals->hLog,
                        (&transGlobals->hLog,
                            "cmEvTransConnectionOnSessionClosed(hsSession = %d(%x), haSession=%x type = cmTransH245Conn)",
                            emaGetIndex((EMAElement)session), session, haTransSession, cmTransH245Conn));

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

                if (!emaWasDeleted((EMAElement)session))
                {
                    int numOfLocks;

                    /* report the actual disconnect */
                    RvLogInfo(&transGlobals->hLog,
                        (&transGlobals->hLog,
                            "cmEvTransConnectionOnSessionClosed(hsSession = %d(%x), haSession=%x type = %d)",
                            emaGetIndex((EMAElement)session), session, haTransSession, host->type));

                    numOfLocks = emaPrepareForCallback((EMAElement)session);
                    transGlobals->sessionEventHandlers.cmEvTransConnectionOnSessionClosed(
                                                              (HSTRANSSESSION)session,
                                                              haTransSession,
                                                              host->type);
                    emaReturnFromCallback((EMAElement)session, numOfLocks);
                }
            }


            if (!emaWasDeleted((EMAElement)session))
            {
                /* disconnect the session from the host */
                if (host->type == cmTransH245Conn)
                {
                    session->H245Connection      = NULL;

                    /* for H.245 there is only one session per host and it's the first that the host points too */
                    nextSess = NULL;
                }
                else
                {
                    if (host == session->Q931Connection)
                        session->Q931Connection = NULL;
                    else
                    if (host == session->annexEConnection)
                        session->annexEConnection = NULL;
                }
            }

            emaUnlock((EMAElement)session);
        }

        /* Get the next session */
        sess = (void *)nextSess;
    }

    /* reinstate the host lock */
    emaReturnFromCallback((EMAElement)host, numOfLocks);

    /* remove it from its hash table */
    if ( (host->hashEntry) && (killHost) )
    {
        RvLogInfo(&transGlobals->hLog,
            (&transGlobals->hLog, "hashDelete = %x",host->hashEntry));

        RvLockGet(&transGlobals->lockHash);
        hashDelete(transGlobals->hHashHosts, host->hashEntry);
        RvLockRelease(&transGlobals->lockHash);
        host->hashEntry = NULL;
    }

    if (!emaWasDeleted((EMAElement)host))
        emaDelete((EMAElement)host);
}

/**************************************************************************************
 * findSessionByMessage
 *
 * Purpose: looks according to the CRV and callID of the message for an entry of the session
 *          in the host's hash table. If none was found, creates an entry.
 *          In case of non-session releated messages (CRV = 0) the routine treats it
 *          as an error and expect the upper layer to handle the case.
 *
 * Input:   transGlobals    - The global data of the transport module.
 *          host            - The host on which the message arrived.
 *          pvtNode         - The decoded message.
 *          isAnnexE        - is the host on which the message came is an annex E host?
 *
 * Output:  session - The session found or created.
 *
 * returned value: RV_TRUE - an error occured, RV_FALSE - all is OK (that doesn't mean that we

⌨️ 快捷键说明

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