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

📄 tpkt.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -