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

📄 rtcp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
**      code.                                                              **
**                                                                         **
**=========================================================================*/

RVAPI
RvInt32 RVCALLCONV rtcpEnd(void)
{
    RvStatus res;
    rvRtcpInstance.timesInitialized--;
    RvRtpEndTimerQueue();
    res = RvRtpEndSelectEngine();
    RvCBaseEnd();
    return res;
}


RVAPI
RvInt32 RVCALLCONV rtcpSetRTCPRecvEventHandler(
    IN HRTCPSESSION         hRTCP,
    IN LPRTCPEVENTHANDLER   rtcpCallback,
    IN void *               context)
{
    rtcpSession *s = (rtcpSession *)hRTCP;
    s->rtcpRecvCallback=rtcpCallback;
    s->haRtcp=context; /*context is Event to inform Ring3 about RTCP arrival*/
    return RV_OK;
}


/*=========================================================================**
**  == rtcpGetAllocationSize()                                             **
**                                                                         **
**  Calculates an allocation size for RTCP session                         **
**                                                                         **
**  PARAMETERS:                                                            **
**      sessionMembers  Maximum number of participants in the session      **
**                                                                         **
**                                                                         **
**  RETURNS:                                                               **
**      If no error occurs, the function returns an allocation size for    **
**      RTCP session.  Otherwise it returns NULL.                          **
**                                                                         **
**=========================================================================*/

RVAPI
int RVCALLCONV rtcpGetAllocationSize(
    IN  int sessionMembers)
{
    return sizeof(rtcpSession) + ALIGNMENT + sizeof(rtcpInfo) * sessionMembers;
}


/************************************************************************************
 * rtcpSetLocalAddress
 * description: Set the local address to use for calls to rtcpOpenXXX functions.
 *              This parameter overrides the value given in rtcpInitEx() for all
 *              subsequent calls.
 * input: ip    - Local IP address to use
 * output: none.
 * return value: Non-negative value on success
 *               Negative value on failure
 ***********************************************************************************/
RVAPI
int RVCALLCONV rtcpSetLocalAddress(IN RvUint32 ip)
{
    rvRtcpInstance.localIp = ip;
    return RV_OK;
}



/*=========================================================================**
**  == rtcpOpenFrom() ==                                                   **
**                                                                         **
**  Opens a new RTCP session in provided buffer.                           **
**                                                                         **
**  PARAMETERS:                                                            **
**      ssrc     The synchronization source value for the RTCP session.    **
**                                                                         **
**      port     The UDP port number to be used for the RTCP session.      **
**                                                                         **
**      cname    A unique name representing the source of the RTP data.    **
**               Must not be NULL.                                         **
**      maxSessionMembers   Maximum number of participants in the session  **
**                                                                         **
**  buffer   pointer to at least rtcpGetAllocationSize byte of memory      **
**                                                                         **
**  bufferSize size of the buffer                                          **
**                                                                         **
**  RETURNS:                                                               **
**      If no error occurs, the function returns a handle for the new      **
**      RTCP session.  Otherwise it returns NULL.                          **
**                                                                         **
**  COMMENTS:                                                              **
**              -----------------------------------------------            **
**     buffer  | rtcpSession |X| participantsArray |X| "mutex" |           **
**              -----------------------------------------------            **
**                            X - alignment area                           **
**=========================================================================*/

RVAPI
HRTCPSESSION RVCALLCONV rtcpOpenFrom(
        IN  RvUint32    ssrc,
        IN  RvUint16    port,
        IN  char *      cname,
        IN  int         maxSessionMembers,
        IN  void *      buffer,
        IN  int         bufferSize)
{
    rtcpSession* s=(rtcpSession*)buffer;
    RvSize_t allocSize=rtcpGetAllocationSize(maxSessionMembers);
    int participantsArrayOfs;
    RvAddress localAddress;
    RvStatus res;

    if ((cname  == NULL) || (strlen(cname) > MAXSDES) || ((int)allocSize > bufferSize))
    {
        return NULL;
    }

    memset(buffer, 0, allocSize);

    s->sessionMembers = 0;
    s->maxSessionMembers = maxSessionMembers;
    s->rtcpRecvCallback = NULL;
    s->isAllocated = RV_FALSE;

    participantsArrayOfs = RvRoundToSize(sizeof(rtcpSession), ALIGNMENT);
    s->participantsArray = (rtcpInfo *) ((char *)s + participantsArrayOfs);
    s->participantsArray[0].ssrc = s->myInfo.ssrc = ssrc;

    RvAddressConstructIpv4(&localAddress, rvRtcpInstance.localIp, port);

    /* Open and bind the socket */
    res = RvSocketConstruct(&s->socket, RV_ADDRESS_TYPE_IPV4, RvSocketProtocolUdp);
    if (res == RV_OK)
    {
        res = RvSocketSetBuffers(&s->socket, 8192, 8192);
        if (res == RV_OK)
            res = RvSocketSetBroadcast(&s->socket, RV_TRUE);
        if (res == RV_OK)
            res = RvSocketSetBlocking(&s->socket, RV_TRUE);
        if (res == RV_OK)
            res = RvSocketBind(&s->socket, &localAddress, NULL);

        if (res != RV_OK)
            RvSocketDestruct(&s->socket, RV_FALSE, NULL);
    }

    RvAddressDestruct(&localAddress);

    if (res != RV_OK)
        return NULL;

    /* Initialize lock in supplied buffer */
    if (RvLockConstruct(&s->lock) != RV_OK)
    {
        RvSocketDestruct(&s->socket, RV_FALSE, NULL);
        return NULL;
    }

    /* Make sure we wait for RTCP packets */
    RvFdConstruct(&s->selectFd, &s->socket);
    RvSelectAdd(RvRtpGetSelectEngine(rvRtcpInstance.selectEngine),
        &s->selectFd, RvSelectRead, rtcpEventCallback);

    setSDES(RTCP_SDES_CNAME, &(s->myInfo.eCName), (RvUint8*)cname, (int)strlen(cname));

    return (HRTCPSESSION)s;
}

/*=========================================================================**
**  == rtcpOpen() ==                                                       **
**                                                                         **
**  Opens a new RTCP session.                                              **
**                                                                         **
**  PARAMETERS:                                                            **
**      ssrc     The synchronization source value for the RTCP session.    **
**                                                                         **
**      port     The UDP port number to be used for the RTCP session.      **
**                                                                         **
**      cname    A unique name representing the source of the RTP data.    **
**               Must not be NULL.                                         **
**                                                                         **
**  RETURNS:                                                               **
**      If no error occurs, the function returns a handle for the new      **
**      RTCP session.  Otherwise it returns NULL.                          **
**                                                                         **
**=========================================================================*/

RVAPI
HRTCPSESSION RVCALLCONV rtcpOpen(
        IN  RvUint32    ssrc,
        IN  RvUint16    port,
        IN  char *      cname)
{
    rtcpSession* s;
    int allocSize = rtcpGetAllocationSize(MAXRTPSESSIONMEMBERS);

    if (RvMemoryAlloc(NULL, (void**)&s, (RvSize_t)allocSize) != RV_OK)
        return NULL;

    if((rtcpSession*)rtcpOpenFrom(ssrc, port, cname, MAXRTPSESSIONMEMBERS, (void*)s, allocSize)==NULL)
    {
        RvMemoryFree(s);
        return NULL;
    }

    s->isAllocated = RV_TRUE;
    return (HRTCPSESSION)s;
}


/*=========================================================================**
**  == rtcpClose() ==                                                      **
**                                                                         **
**  Closes an RTCP session.                                                **
**                                                                         **
**  PARAMETERS:                                                            **
**      hRTCP      The handle of the RTCP session.                         **
**                                                                         **
**  RETURNS:                                                               **
**      A non-negative value upon success, or a negative integer error     **
**      code.                                                              **
**                                                                         **
**=========================================================================*/

RVAPI
RvInt32 RVCALLCONV rtcpClose(
                IN  HRTCPSESSION  hRTCP)
{
    rtcpSession *s = (rtcpSession *)hRTCP;

    if (hRTCP == NULL)
        return RV_ERROR_UNKNOWN;

    /* Cancel the timer is one is active */
    if (s->isTimerSet)
        RvTimerCancel(&s->timer, RV_TRUE);

    RvSelectRemove(RvRtpGetSelectEngine(rvRtcpInstance.selectEngine), &s->selectFd);
    RvFdDestruct(&s->selectFd);

    /* Close the socket */
    RvSocketDestruct(&s->socket, RV_FALSE, NULL);

    /* Destroy the lock */
    RvLockDestruct(&s->lock);

    /* free memory allocated for rtcpSession */
    if (s->isAllocated)
        RvMemoryFree(s);

    return RV_OK;
}


/*=========================================================================**
**  == rtcpSetRemoteAddress() ==                                           **
**                                                                         **
**  Defines the address of the remote peer or of the multicast groop.      **
**                                                                         **
**  PARAMETERS:                                                            **
**      hRTCP    The handle of the RTCP session.                           **
**                                                                         **
**      ip       The IP address to which the RTCP packets will be sent.    **
**                                                                         **
**      port     The UDP port to which the RTCP packets should be sent.    **
**                                                                         **
**  RETURNS:                                                               **
**      A non-negative value upon success, or a negative integer error     **
**      code.                                                              **
**                                                                         **
**=========================================================================*/

RVAPI
void RVCALLCONV rtcpSetRemoteAddress(
                IN  HRTCPSESSION  hRTCP,     /* RTCP Session Opaque Handle */
                IN  RvUint32      ip,        /* target ip address */
                IN  RvUint16      port)      /* target UDP port */
{
    rtcpSession *s = (rtcpSession *)hRTCP;

    if ((ip != 0) && (port != 0))
    {
        if (s->remoteAddressSet)
            RvAddressDestruct(&s->remoteAddress);

        if (RvAddressConstructIpv4(&s->remoteAddress, ip, port) != NULL)
        {
            s->remoteAddressSet = RV_TRUE;

            if (s->isTimerSet == RV_FALSE)
            {
                RvStatus res;

                /* Set a timer */
                /*todo: The timeout should be calculated */
                res = RvTimerStart(&s->timer, RvRtpGetTimerQueue(rvRtcpInstance.timersQueue),
                    RV_TIMER_TYPE_PERIODIC, Rv64Multiply(RV_TIME64_NSECPERSEC, RvInt64Const(5)),
                    rtcpTimerCallback, s);
                if (res == RV_OK)
                    s->isTimerSet = RV_TRUE;
            }
        }
    }
    else
    {
        if (s->remoteAddressSet)
        {
            RvAddressDestruct(&s->remoteAddress);
            s->remoteAddressSet = RV_FALSE;
        }
        rtcpStop(hRTCP);
    }
}


/*=========================================================================**
**  == rtcpStop() ==                                                       **
**                                                                         **
**  Stop RTCP transmisions .                                               **
**                                                                         **
**  PARAMETERS:                                                            **
**      hRTCP    The handle of the RTCP session.                           **
**                                                                         **
**  RETURNS:                                                               **
**      A non-negative value upon success, or a negative integer error     **
**      code.                                                              **
**                                                                         **
**=========================================================================*/

RVAPI
RvInt32 RVCALLCONV rtcpStop(
                IN  HRTCPSESSION  hRTCP)     /* RTCP Session Opaque Handle */
{
    rtcpSession *s = (rtcpSession *)hRTCP;

    /* Cancel the timer if one is active */
    if (s->isTimerSet)
    {
        RvTimerCancel(&s->timer, RV_TRUE);
        s->isTimerSet = RV_FALSE;
    }

    if (s->remoteAddressSet)
        RvAddressDestruct(&s->remoteAddress);

    s->remoteAddressSet = RV_FALSE;

    /* Clear the list*/
    memset(s->participantsArray,0, (RvSize_t)(sizeof(rtcpInfo))*(s->sessionMembers));
    s->myInfo.collision = 0;
    s->myInfo.active = 0;
    s->myInfo.timestamp = 0;
    memset(&(s->myInfo.eSR),0,sizeof(s->myInfo.eSR));

    return RV_OK;
}

/*=========================================================================**
**  == rtcpRTPPacketRecv() ==                                              **
**                                                                         **
**  Informs the RTCP session that a packet was received in the             **
**  corresponding RTP session.                                             **

⌨️ 快捷键说明

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