📄 rtcp_packet.cpp
字号:
// RTCP_Packet.cpp,v 5.5 2003/07/24 22:43:41 parsons Exp
#include "RTCP_Packet.h"
#include "RTP.h"
RTCP_Packet::RTCP_Packet(void)
{
this->chd_.ver_ = 2;
this->chd_.count_ = 0;
this->chd_.pad_ = 0;
this->chd_.length_ = 0;
this->packet_data_ = 0;
}
RTCP_Packet::RTCP_Packet(char* buffer)
{
// Parse the common part of the control packet header.
this->chd_.ver_ = (buffer[0] & 0xC0) >> 6;
if (this->chd_.ver_ != RTP_VERSION)
ACE_DEBUG ((LM_DEBUG,
"RTCP_Packet::RTCP_Packet version incorrect"));
this->chd_.pad_ = (buffer[0] & 0x20) >> 5;
this->chd_.count_ = buffer[0] & 0x1F;
this->chd_.pt_ = buffer[1];
this->chd_.length_ = ntohs(*(ACE_UINT16*)&buffer[2]);
this->packet_data_ = 0;
}
RTCP_Packet::~RTCP_Packet(void)
{
}
void
RTCP_Packet::get_packet_data(char **buffer, ACE_UINT16 &length)
{
length = this->packet_size();
// buiidPacket is defined for each child of RTCP_Packet
// buildPacket creates a snapshot of the RTCP packet in the buffer pktData
this->build_packet ();
*buffer = this->packet_data_;
}
int
RTCP_Packet::is_valid (char is_first)
{
// make sure the RTP version is correct
if (this->chd_.ver_ != RTP_VERSION)
return 0;
// these checks are only for the first RTCP packet in a compound packet
if (is_first)
{
// the payload type must be RR or SR
if ((this->chd_.pt_ != RTCP_PT_SR) && (this->chd_.pt_ != RTCP_PT_RR))
return 0;
// the padding bit must not be set
if (this->chd_.pad_ != 0)
return 0;
}
return 1;
}
/*
* RTCP_BYE_Packet
*/
RTCP_BYE_Packet::RTCP_BYE_Packet(ACE_UINT32 *ssrc_list,
unsigned char length,
const char *text)
{
this->chd_.ver_ = 2;
this->chd_.count_ = length;
this->chd_.pt_ = RTCP_PT_BYE;
if (length)
{
ACE_NEW (this->ssrc_list_,
ACE_UINT32[length]);
this->ssrc_list_length_ = length;
for (int i=0; i<length; i++)
this->ssrc_list_[i] = ssrc_list[i];
}
// Optional - if there is a reason for leaving, store it.
// The reason is padded with extra zeros because the packet must
// end on an even 32-bit boundary.
memset(this->reason_, 0, sizeof(this->reason_));
if (text)
{
size_t text_length = ACE_OS::strlen(text);
memcpy(this->reason_, text, text_length);
this->reason_length_ = ACE_static_cast (unsigned char, text_length);
}
else
this->reason_length_ = 0;
// Set the packet length
this->chd_.length_ = this->chd_.count_ + (this->reason_length_+1)/4;
if ((this->reason_length_+1)%4)
this->chd_.length_++;
this->packet_data_ = 0;
}
//==============================================================================
RTCP_BYE_Packet::RTCP_BYE_Packet(char* buffer, int *len)
: RTCP_Packet(buffer)
{
unsigned int index = 0;
unsigned int j;
// The common part of the header is initialized in the parent.
index=4;
ACE_NEW (this->ssrc_list_,
ACE_UINT32[this->chd_.count_]);
this->ssrc_list_length_ = this->chd_.count_;
// Store the source ids of the sources leaving the session
for (j=0; j<this->chd_.count_; j++)
{
this->ssrc_list_[j] = ntohl(*(ACE_UINT32*)&buffer[index]);
index+=4;
}
// Optional - store the reason for leaving
unsigned int temp = this->chd_.length_; // Borland reports a warning on the
// following line with out this.
memset(this->reason_, 0, sizeof(this->reason_));
if (temp > this->chd_.count_)
{
this->reason_length_ = buffer[index];
index++;
memcpy(this->reason_, &buffer[index], this->reason_length_);
index+=this->reason_length_;
}
else
this->reason_length_ = 0;
// Decrement the length by the size of this message. This is necessary
// because multiple RTCP packets may be contained in a single UDP packet.
*len-=(chd_.length_+1)*4;
this->packet_data_ = 0;
}
//==============================================================================
RTCP_BYE_Packet::~RTCP_BYE_Packet(void)
{
if (this->ssrc_list_)
delete []this->ssrc_list_;
if (this->packet_data_)
delete []this->packet_data_;
}
//==============================================================================
unsigned int
RTCP_BYE_Packet::packet_size(void)
{
ACE_UINT16 size = (1+chd_.count_) * 4;
if (this->reason_length_ > 0)
{
size += this->reason_length_ + 1;
if (size%4)
size += 4 - size%4; // pad with zeros to even 32 bit bound
}
return size;
}
//==============================================================================
void
RTCP_BYE_Packet::ssrc_list(ACE_UINT32 **ssrc_list, unsigned char &length)
{
*ssrc_list = this->ssrc_list_;
length = this->ssrc_list_length_;
}
//==============================================================================
const char *
RTCP_BYE_Packet::reason (void)
{
ACE_CString reason = (const char *)this->reason_;
return reason.c_str();
}
//==============================================================================
void
RTCP_BYE_Packet::build_packet(void)
{
unsigned int index;
unsigned int i;
if (this->packet_data_)
delete []this->packet_data_;
ACE_NEW (this->packet_data_,
char[this->packet_size()]);
index = 0;
this->packet_data_[index] = (this->chd_.ver_ << 6) |
(this->chd_.pad_ << 5) |
this->chd_.count_;
index++;
this->packet_data_[index] = this->chd_.pt_;
index++;
*((ACE_UINT16*)&this->packet_data_[index]) = htons(this->chd_.length_);
index+=2;
for (i=0; i<this->chd_.count_; i++)
{
*((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ssrc_list_[i]);
index+=4;
}
if (this->reason_)
{
this->packet_data_[index] = this->reason_length_;
index++;
memcpy(&this->packet_data_[index], this->reason_, this->reason_length_);
index += this->reason_length_;
while (index < this->packet_size())
{
this->packet_data_[index] = 0;
index ++;
}
}
}
void
RTCP_BYE_Packet::dump (void)
{
ACE_DEBUG ((LM_DEBUG,
"\nRTCP_BYE_Packet:: from ssrc(s) "));
for (int i=0; i< this->ssrc_list_length_; i++)
ACE_DEBUG ((LM_DEBUG,
"%u ",
this->ssrc_list_[i]));
ACE_DEBUG ((LM_DEBUG,
"\n Reason '%s'\n",
this->reason_));
}
RTCP_RR_Packet::RTCP_RR_Packet(ACE_UINT32 ssrc, RR_Block *blocks)
{
RR_Block *block_ptr = blocks;
this->chd_.count_ = 0;
this->chd_.ver_ = 2;
this->chd_.pt_ = RTCP_PT_RR;
this->ssrc_ = ssrc;
this->rr_ = blocks;
while (block_ptr)
{
this->chd_.count_++;
// Can only have 31 receiver reports
if (this->chd_.count_ == 31)
{
block_ptr->next_ = 0;
break;
}
block_ptr = block_ptr->next_;
}
this->chd_.length_ = 1+6*this->chd_.count_; // + profile specific extensions ??
this->packet_data_ = 0;
}
//==============================================================================
RTCP_RR_Packet::RTCP_RR_Packet (char* buffer,
int *len)
:RTCP_Packet (buffer)
{
unsigned int i = 0;
RR_Block *local_block_ptr = 0;
this->rr_ = 0;
// The common part of the header is initialized in the parent.
i=4;
this->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
i+=4;
for (unsigned int j=0; j<this->chd_.count_; j++)
{
if (j==0)
{
ACE_NEW (this->rr_,
RR_Block);
local_block_ptr = this->rr_;
}
else
{
ACE_NEW (local_block_ptr->next_,
RR_Block);
local_block_ptr = local_block_ptr->next_;
}
local_block_ptr->next_ = 0;
local_block_ptr->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
i+=4;
ACE_UINT32 temp = ntohl(*(ACE_UINT32*)&buffer[i]);
local_block_ptr->fraction_ = (temp&0xff000000) >> 24;
local_block_ptr->lost_ = temp & 0x00ffffff;
i+=4;
local_block_ptr->last_seq_ = ntohl(*(ACE_UINT32*)&buffer[i]);
i+=4;
local_block_ptr->jitter_ = ntohl(*(ACE_UINT32*)&buffer[i]);
i+=4;
local_block_ptr->lsr_ = ntohl(*(ACE_UINT32*)&buffer[i]);
i+=4;
local_block_ptr->dlsr_ = ntohl(*(ACE_UINT32*)&buffer[i]);
i+=4;
}
*len-=(this->chd_.length_+1)*4;
this->packet_data_ = 0;
}
//==============================================================================
RTCP_RR_Packet::~RTCP_RR_Packet(void)
{
RR_Block *prev;
if (this->rr_)
{
while (this->rr_)
{
prev = this->rr_;
this->rr_ = this->rr_->next_;
delete prev;
}
}
if (this->packet_data_)
delete []this->packet_data_;
}
//==============================================================================
unsigned int
RTCP_RR_Packet::packet_size(void)
{
ACE_UINT16 size = (2+this->chd_.count_*6) * 4;
return size;
}
//==============================================================================
void
RTCP_RR_Packet::build_packet(void)
{
int index;
RR_Block *local_block_ptr;
if (this->packet_data_)
delete []this->packet_data_;
ACE_NEW (this->packet_data_,
char [this->packet_size ()]);
index = 0;
this->packet_data_[index] = (this->chd_.ver_ << 6) |
(this->chd_.pad_ << 5) |
this->chd_.count_;
index++;
this->packet_data_[index] = chd_.pt_;
index++;
*((ACE_UINT16*)&this->packet_data_[index]) = htons(chd_.length_);
index+=2;
*((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ssrc_);
index+=4;
local_block_ptr = this->rr_;
while (local_block_ptr)
{
*((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->ssrc_);
index+=4;
ACE_UINT32 temp = htonl((local_block_ptr->fraction_&0xff) << 24) &
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -