📄 tpkt.c
字号:
RvUint8 *buffer;
RvBool finished = RV_FALSE;
if (!globals) return RV_ERROR_UNKNOWN;
if (!emaLock((EMAElement)tpkt)) return RV_ERROR_UNKNOWN;
if (tpkt->send.hRpool)
{
emaUnlock((EMAElement)tpkt);
return RV_ERROR_UNKNOWN;
}
/* update the tpkt object with the rpool data */
tpkt->send.hRpool = hRpool;
tpkt->send.message = message;
tpkt->send.offset = offset;
tpkt->send.rpoolLock = rpoolLock;
RvLockGet(rpoolLock);
/* get the total message size */
length = rpoolChunkSize(hRpool, message) - MSG_HEADER_SIZE; /* minus the pointer to the next message */
/* Mark the tpkt header as a new message (tpkt ver) and set into it the length
of the buffer + header */
rpoolGetPtr(tpkt->send.hRpool, tpkt->send.message, tpkt->send.offset, (void **)&buffer);
buffer[0]=tpkt->send.header[0]=3;
buffer[1]=tpkt->send.header[1]=0;
buffer[2]=tpkt->send.header[2]=(unsigned char)((length)>>8);
buffer[3]=tpkt->send.header[3]=(unsigned char)(length);
RvLockRelease(rpoolLock);
/* Do the actual send of header + buffer */
if ((sent=socketSendTcpIfConnected(tpkt, &finished)) < 0)
{
tpkt->send.hRpool = NULL;
emaUnlock((EMAElement)tpkt);
return RV_ERROR_UNKNOWN;
}
/* if all was sent, return the num of bytes sent */
if (finished)
{
tpkt->send.hRpool = NULL;
emaUnlock((EMAElement)tpkt);
return length;
}
/* trigger the write event for the next chunk of data */
tpkt->event=(RvSelectEvents) (tpkt->event | RvSelectWrite);
RvSelectUpdate(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
emaUnlock((EMAElement)tpkt);
return 0;
}
/*******************************************************************************************
* tpktGetAddresses
*
* Purpose: return the addresses associated with the given tpkt object.
*
* Input: hTpkt - A handle to the TPKT module
* Output: localAddress - Local address of the connection. If NULL, not updated
* remoteAddress - Remote address of the connection. If NULL, not updated
*
* Return Value: Non-negative value on success, other on failure
*******************************************************************************************/
RvStatus tpktGetAddresses(
IN HTPKT hTpkt,
OUT cmTransportAddress* localAddress,
OUT cmTransportAddress* remoteAddress)
{
tpktInfo* tpkt = (tpktInfo *)hTpkt;
RvStatus res = RV_ERROR_UNKNOWN;
if (emaLock((EMAElement)tpkt))
{
RvAddress address;
res = RV_OK;
if (localAddress)
{
res = RvSocketGetLocalAddress(&tpkt->connection.socket, &address);
if (res == RV_OK)
{
res = RvH323CoreToCmAddress(&address, localAddress);
RvAddressDestruct(&address);
}
}
if (remoteAddress && (res == RV_OK))
{
res = RvSocketGetRemoteAddress(&tpkt->connection.socket, &address);
if (res == RV_OK)
{
res = RvH323CoreToCmAddress(&address, remoteAddress);
RvAddressDestruct(&address);
}
}
emaUnlock((EMAElement)tpkt);
}
return res;
}
/*******************************************************************************************
* tpktRecvNotify
*
* Purpose: to set a CallBack routine to be called when data arrives.
* This routine is called on EvAccept since it's fast.
*
* Input: hTpkt - A handle to the TPKT module
* eventHandler - The callback to be read on receiving data
* context - To be returned with the callback (may be appl handle etc.)
* Return Value: -1 : on Error;
* 0 : OK
*******************************************************************************************/
int tpktRecvNotify(HTPKT hTpkt,LPTPKTEVENTHANDLER eventHandler,void*context)
{
tpktInfo *tpkt=(tpktInfo*)hTpkt;
tpktGlobals *globals = (tpktGlobals *)emaGetUserData((EMAElement)tpkt);
if (!globals) return RV_ERROR_UNKNOWN;
if (!emaLock((EMAElement)tpkt)) return RV_ERROR_UNKNOWN;
if (tpkt->recv.hRpool)
{
emaUnlock((EMAElement)tpkt);
return RV_ERROR_UNKNOWN;
}
tpkt->recv.context=context;
tpkt->recv.eventHandler=eventHandler;
/* Trigger the evRead event mechanism */
tpkt->event = (RvSelectEvents) (tpkt->event | RvSelectRead);
RvSelectUpdate(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
emaUnlock((EMAElement)tpkt);
return 0;
}
/*******************************************************************************************
* tpktRecvIntoRpool
*
* Purpose: to initiate the reading of a new message while seting a new CallBack routine
* to be called when data arrives.
* The routine handles any problems that arise from the fact that an rpool message
* may be not contiguous.
* This routine is called on each EvRead event, but NOT on EvAccept since it's
* too slow.
*
* Input: hTpkt - A handle to the TPKT module
* buffer - The buffer into which to read the received data
* length - Maximal size of the buffer
*
* Return Value: -1 : on Error;
* 0 : on not receiving a full buffer or a full message;
* >0 : Number of bytes read (may be either the length of the bufer
* in case of an incomplete message or the message length).
*******************************************************************************************/
int tpktRecvIntoRpool(HTPKT hTpkt,
HRPOOL hRpool,
HRPOOLELEM message,
RvLock* rpoolLock)
{
tpktInfo* tpkt=(tpktInfo*)hTpkt;
tpktGlobals* globals = (tpktGlobals *)emaGetUserData((EMAElement)tpkt);
RvSize_t recv = 0;
RvInt32 recv2 = 0;
int length;
RvBool finished = RV_FALSE;
int retVal = 0;
if (!globals) return RV_ERROR_UNKNOWN;
if (!emaLock((EMAElement)tpkt)) return RV_ERROR_UNKNOWN;
if (tpkt->recv.hRpool != NULL)
{
emaUnlock((EMAElement)tpkt);
return RV_ERROR_UNKNOWN;
}
/* update the tpkt object with the rpool data */
tpkt->recv.hRpool = hRpool;
tpkt->recv.message = message;
tpkt->recv.offset = 0;
tpkt->recv.rpoolLock = rpoolLock;
/* get the total message size */
length = rpoolChunkSize(hRpool, message);
/* We can start getting the new message header */
if (socketRecvTcpDirectIfConnected(tpkt,tpkt->recv.header,TPKT_HEADER_SIZE, &recv) != RV_OK)
{
/* We had an error, and the transnet is going to free the rpool buffer -
we should do the same before we let it know of the error */
tpkt->recv.hRpool = NULL;
tpkt->event = (RvSelectEvents) (tpkt->event & ~RvSelectRead);
RvSelectUpdate(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
emaUnlock((EMAElement)tpkt);
return RV_ERROR_UNKNOWN;
}
tpkt->recv.headerCount = recv;
/* we have a valid header */
if (tpkt->recv.headerCount == TPKT_HEADER_SIZE)
{
/* Calculate the message length */
int tpktLen=(((int)(tpkt->recv.header[2])<<8)+tpkt->recv.header[3])-TPKT_HEADER_SIZE;
RvLogDebug(&globals->log, (&globals->log,
"Received header: %02X %02X %02X %02X",
tpkt->recv.header[0], tpkt->recv.header[1], tpkt->recv.header[2], tpkt->recv.header[3]));
/* allocate the rest of the rpool message by the size in the header */
RvLockGet(tpkt->recv.rpoolLock);
rpoolRealloc(tpkt->recv.hRpool, tpkt->recv.message, tpktLen);
RvLockRelease(tpkt->recv.rpoolLock);
/* mark as new message and calculate how many bytes we may attempt to read */
tpkt->recv.header[0]=3;
/* Do the actual reading */
if ((recv2 = socketRecvTcpIfConnected(tpkt, &finished)) < 0)
{
retVal = RV_ERROR_UNKNOWN;
}
else
{
tpkt->recv.headerCount += recv2;
/* we read all we requested */
if (finished)
{
tpkt->recv.hRpool = NULL;
tpkt->event = (RvSelectEvents) (tpkt->event & ~RvSelectRead);
RvSelectUpdate(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
retVal = tpktLen;
}
}
}
if ((retVal == 0) && (!finished))
{
/* We have an incomplete message, set the EvRead event and exit */
tpkt->event = (RvSelectEvents) (tpkt->event | RvSelectRead);
RvSelectUpdate(globals->pSelEngine, &tpkt->connection.fd, tpkt->event, tpktEvent);
}
emaUnlock((EMAElement)tpkt);
return retVal;
}
/*******************************************************************************************
* tpktGetContext
*
* Purpose: return the context of the given tpkt object. The context is the host of this
* connection.
*
* Input: hTpkt - A handle to the TPKT module
*
* Return Value: Context on success, NULL on failure
*******************************************************************************************/
void* tpktGetContext(
IN HTPKT hTpkt)
{
return emaGetApplicationHandle((EMAElement)hTpkt);
}
/*******************************************************************************************
* tpktGetConnection
*
* Purpose: return the connection of the given tpkt object.
*
* Input: hTpkt - A handle to the TPKT module
*
* Return Value: IO connection on success, NULL on failure
*******************************************************************************************/
RvH323Connection* tpktGetConnection(
IN HTPKT hTpkt)
{
tpktInfo* tpkt = (tpktInfo *)hTpkt;
return &tpkt->connection;
}
/*******************************************************************************************
* tpktGetFromConnection
*
* Purpose: return the TPKT object from a connection.
*
* Input: hTpkt - A handle to the TPKT module
*
* Return Value: TPK handle on success, NULL on failure
*******************************************************************************************/
HTPKT tpktGetFromConnection(
IN RvH323Connection* connection)
{
tpktInfo* tpkt;
tpkt = RV_GET_STRUCT(tpktInfo, connection, connection);
return (HTPKT)tpkt;
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -