📄 m803xxrtcp.c
字号:
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 + -