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

📄 rtcp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
                if (fInfo)
                {
                    switch(sdes->type)
                    {
                        case RTCP_SDES_CNAME:
                            memcpy(&(fInfo->eCName), sdes, (RvSize_t)SIZEOF_SDES(*sdes));
                            fInfo->eCName.value[sdes->length] = 0;
                            break;
/* known SDES types that are not handled:
                        case RTCP_SDES_END:
                        case RTCP_SDES_NAME:
                        case RTCP_SDES_EMAIL:
                        case RTCP_SDES_PHONE:
                        case RTCP_SDES_LOC:
                        case RTCP_SDES_TOOL:
                        case RTCP_SDES_NOTE:
                        case RTCP_SDES_PRIV:
                            break;
*/
                        }
                    }

                    scanned += SIZEOF_SDES(*sdes) + sizeof(RvUint32);
                }

            break;
        }

        case RTCP_BYE:
        {
            int i;

            for (i = 0; i < reportCount; i++)
            {
                ConvertFromNetwork(data + scanned, 0, 1);
                info.ssrc = *(RvUint32 *)(data + scanned);
                scanned += sizeof(info.ssrc);

                fInfo = findSSrc(s,info.ssrc);
                if (fInfo)
                {
                    /* We don't really delete this SSRC, we just mark it as invalid */
                    fInfo->invalid = RV_TRUE;
                    fInfo->ssrc    = 0;
                }
            }

            break;
        }

        case RTCP_APP:
            break;
    }

    return RV_OK;
}



static RvBool rtcpTimerCallback(IN void* key)
{
    rtcpSession* s = (rtcpSession*)key;
    RvUint32 data[MAXRTCPPACKET/sizeof(RvUint32)+1];
    RvRtpBuffer buf;

    buf = buffCreate(data, MAXRTCPPACKET);

    rtcpCreateRTCPPacket((HRTCPSESSION)s, &buf);

    RvSocketSendBuffer(&s->socket, buf.buffer, (RvSize_t)buf.length, &s->remoteAddress, NULL);

    return RV_TRUE; /* Make sure the timer is rescheduled */
}


static void rtcpEventCallback(
        IN RvSelectEngine*  selectEngine,
        IN RvSelectFd*      fd,
        IN RvSelectEvents   selectEvent,
        IN RvBool           error)
{
    rtcpSession* s;
    RvUint32 buffer[MAXRTCPPACKET/sizeof(RvUint32)+1];
    RvRtpBuffer buf;
    RvStatus res;
    RvAddress remoteAddress, localAddress;
    RvSize_t bytesReceived;

    RV_UNUSED_ARG(selectEngine);
    RV_UNUSED_ARG(selectEvent);
    RV_UNUSED_ARG(error);

    s = RV_GET_STRUCT(rtcpSession, selectFd, fd);

    buf = buffCreate(buffer, MAXRTCPPACKET);

    res = RvSocketReceiveBuffer(&s->socket, buf.buffer, (RvSize_t)buf.length, &bytesReceived, &remoteAddress);
    if (res == RV_OK)
    {
        buf.length = (RvUint32)bytesReceived;

        RvSocketGetLocalAddress(&s->socket, &localAddress);

        if ((RvAddressGetIpPort(&remoteAddress) != RvAddressGetIpPort(&localAddress)) ||
            !isMyIP(RvAddressIpv4GetIp(RvAddressGetIpv4(&remoteAddress))))
        {
            RvInt32 res=rtcpProcessCompoundRTCPPacket((HRTCPSESSION)s, &buf, getNNTPTime());
            if ((res==0) && (s->rtcpRecvCallback != NULL))
            {
               RvUint32 ssrc=getSSRCfrom(buf.buffer);
               s->rtcpRecvCallback((HRTCPSESSION)s, s->haRtcp, ssrc);
            }
        }
    }
}


static RvUint64 getNNTPTime(void)
{
    RvTime t;
    RvNtpTime ntptime;
    RvUint64 result;

    RvTimeConstruct(&t, 0, 0); /* create and clear time structure */
    RvClockGet(&t); /* Get current wall-clock time */
    RvNtpTimeConstructFromTime(&ntptime, &t, RV_NTPTIME_ABSOLUTE); /* convert to NTP time */
    result = RvNtpTimeTo64(&ntptime, 32, 32); /* Convert to format getNNTPTime returns */
    RvNtpTimeDestruct(&ntptime); /* clean up */
    RvTimeDestruct(&t); /* clean up */

    return result;
}

static RvBool isMyIP(RvUint32 ip)
{
    int i;

    for (i=0; rvRtcpInstance.hostIPs[i]; i++)
    {
        if (ip == rvRtcpInstance.hostIPs[i])
        {
            return RV_TRUE;
        }
    }

    return RV_FALSE;
}

static void setSDES(rtcpSDesType type, rtcpSDES* sdes, RvUint8 *data, int length)
{
    sdes->type   = (unsigned char)type;
    sdes->length = (unsigned char)length;
    memcpy(sdes->value, data, (RvSize_t)length);
    memset(sdes->value+length, 0, (RvSize_t)( 4-((length+2)%sizeof(RvUint32)) ));
}

static void init_seq(rtpSource *s, RvUint16 seq)
{
   s->base_seq       = seq;
   s->max_seq        = seq;
   s->bad_seq        = RTP_SEQ_MOD + 1;
   s->cycles         = 0;
   s->received       = 0;
   s->received_prior = 0;
   s->expected_prior = 0;
}


static int update_seq(rtpSource *s, RvUint16 seq, RvUint32 ts, RvUint32 arrival)
{
    RvUint16 udelta = (RvUint16)(seq - s->max_seq);

    if (s->probation)
    {
        if (seq == s->max_seq + 1)
        {
            s->probation--;
            s->max_seq = seq;
            if (s->probation == 0)
            {
                init_seq(s, seq);
                s->received++;
                return 1;
            }
        }
        else
        {
            s->probation = MIN_SEQUENTIAL - 1;
            s->max_seq = seq;
        }
        return RV_OK;
    }
    else if (udelta < MAX_DROPOUT)
    {
        if (seq < s->max_seq) s->cycles += RTP_SEQ_MOD;
        s->max_seq = seq;
    }
    else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER)
    {
        if (seq == s->bad_seq)
        {
            init_seq(s, seq);
        }
        else
        {
            s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
            return RV_OK;
        }
    }
    else
    {
   /* duplicate or reordered packet */
    }
    {
        RvInt32 transit = (RvInt32)(arrival - ts);
        RvInt32 d = (RvInt32)(transit - s->transit);
        s->transit = transit;
        if (d < 0) d = -d;
        s->jitter += d - ((s->jitter + 8) >> 4);
    }
    s->received++;
    return 1;
}


/*=========================================================================**
**  == makeHeader() ==                                                     **
**                                                                         **
**  Creates an RTCP packet header.                                         **
**                                                                         **
**  PARAMETERS:                                                            **
**      ssrc       A synchronization source value for the RTCP session.    **
**                                                                         **
**      count      A count of sender and receiver reports in the packet.   **
**                                                                         **
**      type       The RTCP packet type.                                   **
**                                                                         **
**      dataLen    The length of the data in the packet buffer, in         **
**                 octets, including the size of the header.               **
**                                                                         **
**  RETURNS:                                                               **
**      The function returns a header with the appropriate parameters.     **
**                                                                         **
**=========================================================================*/

static rtcpHeader makeHeader(RvUint32 ssrc, RvUint8 count, rtcpType type,
                             RvUint16 dataLen)
{
    rtcpHeader header;

    header.ssrc = ssrc;

    header.bits = RTCP_HEADER_INIT;
    header.bits = bitfieldSet(header.bits, count, HEADER_RC, HDR_LEN_RC);
    header.bits = bitfieldSet(header.bits, type,  HEADER_PT, HDR_LEN_PT);
    header.bits = bitfieldSet(header.bits, W32Len(dataLen) - 1, HEADER_len, HDR_LEN_len);

    ConvertToNetwork(&header, 0, W32Len(SIZEOF_RTCPHEADER));

    return header;
}


static RvUint32 getLost(rtpSource *s)
{
    RvUint32 extended_max;
    RvUint32 expected;
    RvInt32 received_interval;
    RvInt32 expected_interval;
    RvInt32 lost;
    RvInt32 lost_interval;
    RvUint8 fraction;

    extended_max = s->cycles + s->max_seq;
    expected = extended_max - s->base_seq + 1;
    lost = expected - s->received;
    expected_interval = expected - s->expected_prior;
    s->expected_prior = expected;
    received_interval = s->received - s->received_prior;
    s->received_prior = s->received;
    lost_interval = expected_interval - received_interval;

    if (expected_interval == 0  ||  lost_interval <= 0)
        fraction = 0;
    else
        fraction = (RvUint8)((lost_interval << 8) / expected_interval);

    return (fraction << 24) + lost;
}


static RvUint32 getJitter(rtpSource *s)
{
    return s->jitter >> 4;
}

static RvUint32 getSequence(rtpSource *s)
{
    return s->max_seq + s->cycles;
}



static RvUint32 getSSRCfrom(RvUint8 *head)
{
   RvUint8 *ssrcPtr = (RvUint8 *)head + sizeof(RvUint32);
   return *(RvUint32 *)(ssrcPtr);
}


static rtcpInfo *findSSrc(rtcpSession *s, RvUint32 ssrc)
{
    int     index = 0;
    RvBool  doAgain = RV_TRUE;
    rtcpInfo *pInfo;
    if (s == NULL)
        return NULL;

    /* Look for the given SSRC */
    while ((doAgain) && (index < s->sessionMembers))
    {
       if (s->participantsArray[index].ssrc == ssrc)
            doAgain = RV_FALSE;
       else
           index ++;

    }
    if (index < s->sessionMembers )
        pInfo = &s->participantsArray[index];
    else
        pInfo = NULL;

    return pInfo;
}


static rtcpInfo *insertNewSSRC(rtcpSession *s, RvUint32 ssrc)
{
    rtcpInfo* pInfo = NULL;
    int index;

    if (s->sessionMembers >= s->maxSessionMembers)
    {
        /* We've got too many - see if we can remove some old ones */
        index = 0;
        while ((index < s->sessionMembers) &&
               (s->participantsArray[index].invalid && s->participantsArray[index].ssrc == 0))
            index++;
    }
    else
    {
        /* Add it as a new one to the list */
        index = s->sessionMembers;
        s->sessionMembers++;
    }

    if (index < s->sessionMembers)
    {
        /* Got a place for it ! */
        pInfo = &s->participantsArray[index];
        memset(pInfo, 0, sizeof(rtcpInfo));
        pInfo->ssrc          

⌨️ 快捷键说明

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