📄 tpkt.c
字号:
tpkt->recv.eventHandler((HTPKT)tpkt,selectEvent,tpktLen,RV_FALSE,tpkt->recv.context);
emaReturnFromCallback((EMAElement)tpkt, numOfLocks);
}
}
}
break;
/* Treat the event of closing of a connection */
case RvSelectClose:
{
RvLogDebug(&globals->log, (&globals->log,
"tpktEvent(connection=%p, RvSelectClose, error=%d, context=%p)", connection, error, globals));
/* In case we are not in a closing process already */
if (!tpkt->close)
{
/* mark the connection as closing */
tpkt->close = RV_TRUE;
/* notify that the close occured (as a recv event) */
if (tpkt->recv.eventHandler != NULL)
{
int numOfLocks;
numOfLocks = emaPrepareForCallback((EMAElement)tpkt);
tpkt->recv.eventHandler((HTPKT)tpkt,selectEvent,0,RV_FALSE,tpkt->recv.context);
emaReturnFromCallback((EMAElement)tpkt, numOfLocks);
}
else
/* if no recv callback use the send callback (?) */
if (tpkt->send.eventHandler != NULL)
{
int numOfLocks;
numOfLocks = emaPrepareForCallback((EMAElement)tpkt);
tpkt->send.eventHandler((HTPKT)tpkt,selectEvent,0,RV_FALSE,tpkt->send.context);
emaReturnFromCallback((EMAElement)tpkt, numOfLocks);
}
}
/* if we already got a close event on this connection */
else
{
/* Close the tpkt object */
tpktClose((HTPKT)tpkt);
}
}
break;
}
emaUnlock((EMAElement)tpkt);
}
/*******************************************************************************************
* tpktOpen
*
* Purpose: Allocate a socket and start either a connect process in case of a client which
* supplied a full address, or a listenning process in case of server.
* For a client that didn't supply an address yet, just create the socket.
*
* Input: hTpktCtrl - Handle to the tpkt instance
* localAddress - Local address to use
* connectionType - What type of connection we request (Tcp or TcpServer)
* standard - Standard to use on connection (Q931 or H245)
* context - Additional data to be supplied on the callback
*
* Return Value: A handle to the tpkt object created
*******************************************************************************************/
HTPKT tpktOpen(
IN HTPKTCTRL hTpktCtrl,
IN cmTransportAddress* localAddress,
IN RvH323ConnectionType connType,
IN tpktTypes tpktType,
IN LPTPKTEVENTHANDLER eventHandler,
IN void* context)
{
tpktGlobals* globals = (tpktGlobals *)hTpktCtrl;
RvAddress coreAddress, *pCoreAddress;
tpktInfo* tpktNew;
RvStatus res;
RvLogEnter(&globals->log, (&globals->log, "tpktOpen"));
tpktNew = (tpktInfo *)emaAdd(globals->hEma, context);
/* check that an element was created */
if (tpktNew == NULL)
{
RvLogLeave(&globals->log, (&globals->log, "tpktOpen - Out of resoruces"));
return NULL;
}
memset(tpktNew, 0, sizeof(tpktInfo));
if (localAddress == NULL)
pCoreAddress = NULL;
else
{
RvH323CmToCoreAddress(localAddress, &coreAddress);
pCoreAddress = &coreAddress;
}
/* Create an IO connection to work with */
tpktNew->connection.type = RvH323ConnectionNone;
tpktNew->connection.context = globals;
res = RvSocketConstruct(&tpktNew->connection.socket, RV_ADDRESS_TYPE_IPV4, RvSocketProtocolTcp);
if (res != RV_OK)
{
RvLogLeave(&globals->log, (&globals->log, "tpktOpen - Error constructing a connection (%d)", res));
emaDelete((EMAElement)tpktNew);
return NULL;
}
/* We're always working with non-blocking sockets */
RvSocketSetBlocking(&tpktNew->connection.socket, RV_FALSE);
{
int optval = 1;
setsockopt (tpktNew->connection.socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval));
}/**so we can reuse the port**/
/* bind it to the listening address */
if (RvSocketBind(&tpktNew->connection.socket, pCoreAddress, globals->pPortRange) != RV_OK)
{
/* todo: h.e (by the way we have this peace of code 3 times)
(probably "goto" is not so bad ) */
RvSocketDestruct(&tpktNew->connection.socket, RV_TRUE, globals->pPortRange);
RvLogLeave(&globals->log, (&globals->log, "tpktOpen - Error listening (%d)", res));
emaDelete((EMAElement)tpktNew);
return NULL;
}
/* for server - start listenning on the socket */
if ((tpktType == tpktMultiServer) || (tpktType == tpktServer))
{
/* Listen to incoming connections */
if ((RvSocketListen(&tpktNew->connection.socket, 16) != RV_OK) ||
(RvFdConstruct(&tpktNew->connection.fd, &tpktNew->connection.socket) != RV_OK))
{
RvSocketDestruct(&tpktNew->connection.socket, RV_TRUE, globals->pPortRange);
RvLogLeave(&globals->log, (&globals->log, "tpktOpen - Error listening (%d)", res));
emaDelete((EMAElement)tpktNew);
return NULL;
}
else
{
tpktNew->event = RvSelectAccept;
if (RvSelectAdd(globals->pSelEngine, &tpktNew->connection.fd, tpktNew->event, tpktEvent) != RV_OK)
{
RvFdDestruct(&tpktNew->connection.fd);
RvSocketDestruct(&tpktNew->connection.socket, RV_TRUE, globals->pPortRange);
RvLogLeave(&globals->log, (&globals->log, "tpktOpen - Error adding to Select (%d)", res));
emaDelete((EMAElement)tpktNew);
return NULL;
}
}
}
tpktNew->connection.type = connType;
/* Initialize the TPKT object */
tpktNew->type = tpktType;
tpktNew->bytesLeftToRead = TPKT_HEADER_SIZE;
tpktNew->readingHeader = RV_TRUE;
tpktNew->errorEncountered = RV_FALSE;
tpktNew->header[0] = 0; /* Mark header as empty */
tpktNew->send.eventHandler=eventHandler;
tpktNew->recv.eventHandler=eventHandler;
tpktNew->send.context=context;
tpktNew->recv.context=context;
RvLogLeave(&globals->log, (&globals->log, "tpktOpen(hTpkt=%p)=%d", tpktNew, res));
return (HTPKT)tpktNew;
}
/*******************************************************************************************
* tpktConnect
*
* Purpose: This routine supplements the tpktOpen routine, for clients which didn't supply
* an address and now wish to do the actual connect operation on the already allocated
* socket.
*
* Input: hTpkt - Handle to the tpktInfo element
* remoteAddress - Address to connect to
*
* Return Value: Non-negative value on success, other on failure
*******************************************************************************************/
int tpktConnect(IN HTPKT hTpkt, IN cmTransportAddress* remoteAddress)
{
tpktInfo* tpkt = (tpktInfo *)hTpkt;
tpktGlobals* globals = (tpktGlobals *)emaGetUserData((EMAElement)tpkt);
RvAddress coreAddress;
RvStatus status = RV_ERROR_UNKNOWN;
if (globals == NULL)
return RV_ERROR_NULLPTR;
if (emaLock((EMAElement)tpkt))
{
/* Let's try to connect it */
RvH323CmToCoreAddress(remoteAddress, &coreAddress);
#if (RV_OS_TYPE != RV_OS_TYPE_WIN32)
status = RvSocketConnect(&tpkt->connection.socket, &coreAddress);
if (status == RV_OK)
#endif
{
/* the other side, if listening, will consider the socket connected - so should we */
tpkt->event = RvSelectConnect;
tpkt->isConnected = RV_TRUE;
/* set event for socket */
RvFdConstruct(&tpkt->connection.fd, &tpkt->connection.socket);
RvSelectAdd(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
}
#if (RV_OS_TYPE == RV_OS_TYPE_WIN32)
status = RvSocketConnect(&tpkt->connection.socket, &coreAddress);
#endif
RvAddressDestruct(&coreAddress);
emaUnlock((EMAElement)tpkt);
}
return status;
}
/*******************************************************************************************
* tpktClose
*
* Purpose: Starts the closing procedure of a tpkt object.
* Frees all its resources if an Idle event won't arrive from the IO layer for the
* TPKT object.
*
* Input: hTpkt - Handle to the tpktInfo element
*
* Return Value: Non-negative value on success, other on failure
*******************************************************************************************/
int tpktClose(IN HTPKT hTpkt)
{
tpktInfo* tpkt = (tpktInfo *)hTpkt;
tpktGlobals* globals = (tpktGlobals *)emaGetUserData((EMAElement)tpkt);
RvStatus res = RV_ERROR_UNKNOWN;
if (globals == NULL)
return RV_ERROR_NULLPTR;
if (!emaLock((EMAElement)tpkt)) return RV_ERROR_DESTRUCTED;
RvLogInfo(&globals->log, (&globals->log, "tpktClose(HTPKT %p)", hTpkt));
/* if indeed the connection is connected and not yet in a closing state */
if ((tpkt->isConnected == RV_TRUE) && !tpkt->close)
{
/* Mark the connection as closing */
tpkt->close = RV_TRUE;
/* make sure we're called for the grand closing */
tpkt->event = (RvSelectEvents) (RvSelectRead | RvSelectClose);
RvSelectUpdate(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
/* now close */
res = RvSocketShutdown(&tpkt->connection.socket, RV_TRUE);
if(res != RV_OK)
{
/* In case of an error trying to close the TPKT gracefully, we just brotally
kill it and get it all over with */
RvSelectRemove(globals->pSelEngine, &tpkt->connection.fd);
RvFdDestruct(&tpkt->connection.fd);
res = RvSocketDestruct(&tpkt->connection.socket, RV_FALSE, globals->pPortRange);
emaDelete((EMAElement)tpkt);
/* Make sure we unlink the host from this TPKT element, so it won't mess up the
deletion procedure
emaSetApplicationHandle((EMAElement)tpkt, NULL);*/
}
/* Mark this session as being in the closing process */
tpkt->isConnected = RV_FALSE;
}
else
{
/* The connection is already closing -
Vehemently close the socket and release the tpkt object */
if (tpkt->event != 0)
{
/* We have an event to remove */
RvSelectRemove(globals->pSelEngine, &tpkt->connection.fd);
RvFdDestruct(&tpkt->connection.fd);
}
res = RvSocketDestruct(&tpkt->connection.socket, RV_FALSE, globals->pPortRange);
emaDelete((EMAElement)tpkt);
}
emaUnlock((EMAElement)tpkt);
return res;
}
/*******************************************************************************************
* tpktSendFromRpool
*
* Purpose: This routine sends a given rpool message over a connection, assuming that the message
* already contains a tpkt header.
*
* Input: hTpkt - Handle to the tpktInfo element
* hRpool - handle to the rpool.
* message - points to the message to be sent.
* offset - where in the message to start the sending.
* rpoolLock - The lock of the rpool
*
* Return Value: 0 or RV_ERROR_UNKNOWN
*******************************************************************************************/
int tpktSendFromRpool(HTPKT hTpkt,
HRPOOL hRpool,
HRPOOLELEM message,
int offset,
RvLock* rpoolLock)
{
tpktInfo *tpkt=(tpktInfo*)hTpkt;
tpktGlobals *globals = (tpktGlobals *)emaGetUserData((EMAElement)tpkt);
int sent;
int length;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -