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

📄 m803xxrtcp.c

📁 m80320 VoIP DSP驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    int lost,lost_interval;
    unsigned char fraction;

    /*The number of packets lost is defined to be the number of packets*/
    /*expected less the number of packets actually received:*/
    extended_max = RTCPInfo[PortNo].Cycles + RTCPInfo[PortNo].MaxSeq;
    expected = extended_max - RTCPInfo[PortNo].BaseSeq + 1;

    lost = expected - RTCPInfo[PortNo].Received;

    /*   The fraction of packets lost during the last reporting interval*/
    /*   (since the previous SR or RR packet was sent) is calculated from*/
    /*   differences in the expected and received packet counts across the*/
    /*   interval, where expected_prior and received_prior are the values*/
    /*   saved when the previous reception report was generated:*/
    expected_interval = expected - RTCPInfo[PortNo].ExpectedPrior;
    RTCPInfo[PortNo].ExpectedPrior = expected;
    received_interval = RTCPInfo[PortNo].Received - RTCPInfo[PortNo].ReceivedPrior;
    RTCPInfo[PortNo].ReceivedPrior = RTCPInfo[PortNo].Received;
    lost_interval = expected_interval - received_interval;
    if (expected_interval == 0 || lost_interval <= 0)
        fraction = 0;
    else
        fraction = (unsigned char)((unsigned int)((unsigned int)lost_interval << 8) / expected_interval);

    /*fill the parameters*/
    LRTCPPacket->Report.RR[0].RTCPCumLost=lost & 0xffffff ;
    LRTCPPacket->Report.RR[0].RTCPFraction=fraction ;
}


/******************************************************************************/
/* Function name: RTCPInitSeq                                                 */
/* Description  : initialize some RTP sequence counting parameters            */
/* Return type  : void                                                        */
/* Argument     : PortNo -- The channel on the ipp board                      */
/*                seq -- the sequence number of the RTP packet                */
/* Author/Date  :                                                             */
/* Note:          called at arrival of first RTP packet.                      */
/******************************************************************************/
void RTCPInitSeq(UINT8 PortNo, unsigned short seq)
{
    RTCPInfo[PortNo].BaseSeq = seq /*- 1*/;
    RTCPInfo[PortNo].MaxSeq = seq;
    RTCPInfo[PortNo].BadSeq = RTP_SEQ_MOD + 1;
    RTCPInfo[PortNo].Cycles = 0;
    RTCPInfo[PortNo].Received = 0;
    RTCPInfo[PortNo].ReceivedPrior = 0;
    RTCPInfo[PortNo].ExpectedPrior = 0;
}


/******************************************************************************/
/* Function name: RTCPUpdateSeq                                               */
/* Description  : updates the RTP sequence counting parameters.               */
/* Return type  : 1 - Success, 0 - Failed (Bad sequence number)               */
/* Argument     : PortNo -- The channel on the ipp board                      */
/*                seq -- the sequence number of the RTP packet                */
/*                ssrc  - the SSRC of the source                              */
/* Author/Date  :                                                             */
/* Note:          called at the arrival of EACH RTP packet                    */
/******************************************************************************/
int RTCPUpdateSeq(UINT8 PortNo, unsigned short Seq,unsigned int ssrc)
{
    unsigned short udelta ;

    RTCPInfo[PortNo].PacketRcvdSinceSR=1;
    udelta = Seq - RTCPInfo[PortNo].MaxSeq;

    /*first packet received from the source*/
    if (!RTCPInfo[PortNo].SomePacketReceived)
    {
        RTCPInitSeq(PortNo,Seq);
        RTCPInfo[PortNo].SomePacketReceived=1;
        RTCPInfo[PortNo].RemoteSSRC=ssrc;
    }
    else if (udelta < RTP_MAX_DROPOUT)
    {
        /* in order, with permissible gap */
        if (Seq < RTCPInfo[PortNo].MaxSeq)
        {
            /* Sequence number wrapped - count another 64K cycle.*/
            RTCPInfo[PortNo].Cycles += RTP_SEQ_MOD;
        }
        RTCPInfo[PortNo].MaxSeq = Seq;
    }
    else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER)
    {
        /* the sequence number made a very large jump */
        if (Seq == RTCPInfo[PortNo].BadSeq)
        {
            /* Two sequential packets -- assume that the other side*/
            /* restarted without telling us so just re-sync*/
            /* (i.e., pretend this was the first packet).*/
            RTCPInitSeq(PortNo,Seq);
        }
        else
        {
            /* keep the bad sequence number to check if the other side restarted*/
            RTCPInfo[PortNo].BadSeq = (Seq + 1) & (RTP_SEQ_MOD-1);
            return 0;
        }
    }
    else
    {
       /* duplicate or reordered packet */
    }

    RTCPInfo[PortNo].Received++;
    return 1;
}


/***********************************************************************************/
/* Function name: RTCPPacketValidate                                               */
/* Description  : performs validity check on an RTCP compound packet (UDP packet)  */
/* Return type  : 0 - Success, 1,2 - Failed                                        */
/* Argument     : Buffer - pointer to the compound RTCP (UDP) packet.              */
/*                PacketLen  - length of compound RTCP packet in words             */
/* Author/Date  :                                                                  */
/* Note:          called at the arrival of EACH RTP packet                         */
/***********************************************************************************/
int RTCPPacketValidate(char *Buffer,unsigned int PacketLen)
{
    TRTCP *RTCPPacketEnd;
    TRTCP *RTCPPacket=(TRTCP*)Buffer;

    /*check the first header*/
    if ((RTCPPacket->Common.RTCPVer!=2) || (RTCPPacket->Common.RTCPPT<RTCP_SR) || (RTCPPacket->Common.RTCPPT>RTCP_APP))
        return (1); /* something wrong with packet format*/

    RTCPPacketEnd = (TRTCP *)((unsigned char *)RTCPPacket + PacketLen);

    /*check the version field in other packets*/
    do
#if INSTALL_ON_IXP1200
    RTCPPacket  = (TRTCP *)((unsigned int *)RTCPPacket + RTCPPacket->Common.RTCPLength + 1);    
#else       /*PPC 8240*/
    RTCPPacket  = (TRTCP *)((unsigned int *)RTCPPacket + US_SWAP(RTCPPacket->Common.RTCPLength) + 1);
#endif
    while (RTCPPacket < RTCPPacketEnd && RTCPPacket->Common.RTCPVer == 2);

    if (RTCPPacket  != RTCPPacketEnd)
        return (2); /* something wrong with packet format*/

    return (0);
}


/***************************************************************************************/
/* Function name: RTCPBuildSRPacket                                                    */
/* Description  : builds Sender Report packet With optional Receiver Report            */
/* Return type  : char* - pointer to the end of the packet + 1 (start of next packet)  */
/* Argument     : PortNo - the channel on the board                                       */
/*                Buffer  - pointer to buffer to hold the packet,                      */
/*                         The USER MUST SUPPLY ENOUGH SPACE FOR THE PACKET!           */
/* Author/Date  :                                                                      */
/* Note:          called before sending RTCP packet                                    */
/***************************************************************************************/
TRTCP *RTCPPacket;
char *RTCPBuildSRPacket(UINT8 PortNo,char *Buffer)
{
    RTCPReport *PacketEnd;
    unsigned int delta,frac;

    RTCPPacket=(TRTCP*)Buffer;

    /*Header*/
    RTCPPacket->Common.RTCPVer=RTP_VERSION;
    RTCPPacket->Common.RTCPPadding=0;
    RTCPPacket->Common.RTCPCount=0;
    RTCPPacket->Common.RTCPPT=RTCP_SR;
    RTCPPacket->Common.RTCPSsrc=Swap_DwordM((((RTCPInfo[PortNo].RTPSSRC)&0xff000000)>>8)
                                            |(((RTCPInfo[PortNo].RTPSSRC)&0x00ff0000)<<8)
                                            |(((RTCPInfo[PortNo].RTPSSRC)&0x0000ff00)>>8)
                                            |(((RTCPInfo[PortNo].RTPSSRC)&0x000000ff)<<8)
                                           );
    /*SR*/
    RTCPPacket->Report.SR.RTCPNtpSec=Swap_DwordM(RTCP_NTP_SEC(PortNo));
    RTCPPacket->Report.SR.RTCPNtpFrac=Swap_DwordM(RTCP_NTP_FRAC(PortNo));
    RTCPPacket->Report.SR.RTCPTs=Swap_DwordM(RecordRTPTimeStamp[PortNo]);

    RTCPPacket->Report.SR.RTCPPsent=Swap_DwordM(RTCPInfo[PortNo].SenderPacketCount);
    RTCPPacket->Report.SR.RTCPOsent=Swap_DwordM(RTCPInfo[PortNo].SenderOctetCount);
    RTCPPacket->Common.RTCPLength=Swap_WordM((((unsigned int)(&(RTCPPacket->Report.SR.RR[0]))-(unsigned int)(Buffer))/sizeof(unsigned int))-1);
    PacketEnd=(RTCPReport*)(&(RTCPPacket->Report.SR.RR[0]));

    /*RR*/
#if 1
    if (RTCPInfo[PortNo].PacketRcvdSinceSR)
    {
        /*fill fraction and cumolative losts*/
        RTCPSRLostFill(RTCPPacket,PortNo);
        /*fill other params*/
        RTCPPacket->Report.SR.RR[0].RTCPSsrc    =(((RTCPInfo[PortNo].RemoteSSRC)&0xffff0000)>>16)
                                            |(((RTCPInfo[PortNo].RemoteSSRC)&0x0000ffff)<<16);
        RTCPPacket->Report.SR.RR[0].RTCPLast_seq=(((UINT32)RTCPInfo[PortNo].MaxSeq)<<16)&0xffff0000;
              RTCPPacket->Report.SR.RR[0].RTCPJitter  =RTCPJitter(PortNo,0,0,0);
        RTCPPacket->Report.SR.RR[0].RTCPLsr     =RTCPInfo[PortNo].Lsr;

              delta=(unsigned int)(RecordRTPTimeStamp[PortNo]-RTCPInfo[PortNo].LastSRArrival);

              /*this is the equivelent of 65536/8000=8.192*/
        frac =(unsigned int)((unsigned int)delta*(unsigned int)192);
              frac =(unsigned int)((unsigned int)frac/(unsigned int)1000);
        RTCPPacket->Report.SR.RR[0].RTCPDlsr=(unsigned int)((unsigned int)delta*(unsigned int)8)+(unsigned int)frac;

        RTCPPacket->Common.RTCPLength=Swap_WordM((((unsigned int)(&(RTCPPacket->Report.SR.RR[1]))-(unsigned int)(Buffer))/sizeof(unsigned int))-1);
        RTCPPacket->Common.RTCPCount=1;
        PacketEnd=(RTCPReport*)(&(RTCPPacket->Report.SR.RR[1]));
    }
#endif
    /*add extension if necessary*/
    if (RTCPInfo[PortNo].TxExtLength)
    {
       memcpy((char *)PacketEnd,RTCPInfo[PortNo].TxExtension,RTCPInfo[PortNo].TxExtLength);
       RTCPPacket->Common.RTCPLength+=RTCPInfo[PortNo].TxExtLength/sizeof(unsigned int);
       /*(PacketEnd+=RTCPInfo[PortNo].TxExtLength;*/
       PacketEnd = (RTCPReport *)((char *)PacketEnd + RTCPInfo[PortNo].TxExtLength);
       if(RTCPInfo[PortNo].SendExtOnce)
           RTCPInfo[PortNo].TxExtLength=0;
    }

    /*send event to PC*/
    RTCPRepBuff[PortNo].PacketCount  =(unsigned int )RTCPPacket->Report.SR.RTCPPsent  ;
    RTCPRepBuff[PortNo].OctetCount   =(unsigned int )RTCPPacket->Report.SR.RTCPOsent  ;
    RTCPRepBuff[PortNo].RoundTrip    =(unsigned int )0;
    RTCPRepBuff[PortNo].ReportType   =RTCP_SR_Tx;
    if (RTCPInfo[PortNo].PacketRcvdSinceSR)
    {
#if 1
        RTCPRepBuff[PortNo].Jitter       =(unsigned int )RTCPPacket->Report.SR.RR[0].RTCPJitter;
        RTCPRepBuff[PortNo].CumLost      =(unsigned int )(RTCPPacket->Report.SR.RR[0].RTCPCumLost & 0xFFFFFFFF);
        RTCPRepBuff[PortNo].FractionLost =(unsigned int )(RTCPPacket->Report.SR.RR[0].RTCPFraction & 0xFFFFFFFF);
        RTCPRepBuff[PortNo].ExtHighSeq   =(unsigned int )RTCPPacket->Report.SR.RR[0].RTCPLast_seq ;
#endif
    }
    else
    {
        RTCPRepBuff[PortNo].Jitter       =(unsigned int )-1;
        RTCPRepBuff[PortNo].CumLost      =(unsigned int )-1;
        RTCPRepBuff[PortNo].FractionLost =(unsigned int )-1;
        RTCPRepBuff[PortNo].ExtHighSeq   =(unsigned int )-1;
    }

    RtpValue[PortNo].Sender_SrTime = 0;

    RTCPInfo[PortNo].PacketRcvdSinceSR=0;
    RTCPInfo[PortNo].PacketSentSinceSR=0;
    /***************************************************************************************
     RTCP报文的描述信息:
            0x 81 CA 00 06 -------0006 表示后面数据的长度,单位为4字节的整数倍,6*4 = 24字节
            0x ** ** ** ** -------     表示id标识符
            0x ## ** ?? ?? ------- ##  表示类型: 0--END 1--USERNAME AND DOMAIN 
            0x ?? ?? ?? ??                       2--HOST NAME ,其他的请参考其他书籍
            ..............         **  表示数据的长度
                                   ??  表示数据
                                   注意:后面可以有多个重复来表示不同的数据
            结尾最后一个字节用00表示END

     yuhongtao     2006-09-22
    ****************************************************************************************/
/* gateway name "zte-zxr10gar-voip" */
    *((UINT32 *)PacketEnd) = Swap_DwordM(0x81ca0006);

⌨️ 快捷键说明

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