📄 transutil.c
字号:
*
**************************************************************************************/
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 + -