summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp1212
1 files changed, 1212 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp b/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp
new file mode 100644
index 00000000000..8ef82e30bb3
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/AV/RTCP_Packet.cpp
@@ -0,0 +1,1212 @@
+// $Id$
+#include "orbsvcs/AV/RTCP_Packet.h"
+#include "orbsvcs/AV/RTP.h"
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+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 = static_cast<ACE_UINT16> (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_ = static_cast<unsigned char> (text_length);
+ }
+ else
+ this->reason_length_ = 0;
+
+ // Set the packet length
+ this->chd_.length_ = static_cast<ACE_UINT16> (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 = static_cast<ACE_UINT16> ((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] = static_cast<char> ((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_ = static_cast<ACE_UINT16> (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 = static_cast<ACE_UINT16> ((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] = static_cast<char> ((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) &
+ local_block_ptr->lost_;
+ *((ACE_UINT32*)&this->packet_data_[index]) = temp;
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->last_seq_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->jitter_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->lsr_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->dlsr_);
+ index+=4;
+ local_block_ptr = local_block_ptr->next_;
+ }
+}
+
+void
+RTCP_RR_Packet::dump (void)
+{
+ RR_Block *b = this->rr_;
+ int count = 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_RR_Packet:: from %u - %d rr blocks follow.\n",
+ this->ssrc_,
+ this->chd_.count_));
+
+ while (b)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ " Block %d: ssrc %u; frac %u; lost %u; last seq %u\n",
+ count,
+ b->ssrc_,
+ b->fraction_,
+ b->lost_,
+ b->last_seq_));
+ ACE_DEBUG ((LM_DEBUG,
+ " jitter %u; lsr %u; dlsr %u;\n",
+ b->jitter_,
+ b->lsr_,
+ b->dlsr_));
+
+ b = b->next_;
+ ++count;
+ }
+}
+
+
+RTCP_SDES_Packet::RTCP_SDES_Packet(void) :
+ RTCP_Packet ()
+{
+ this->chd_.pt_ = RTCP_PT_SDES;
+ this->chunk_ = 0;
+ this->packet_data_ = 0;
+ this->num_chunks_ = 0;
+// this->num_items_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SDES_Packet::RTCP_SDES_Packet(char* buffer, int *len):
+ RTCP_Packet (buffer)
+{
+ unsigned int i;
+ sdesChunk_t *cp = 0; // pointer to chunk
+ sdesItem_t *ip = 0; // pointer to item
+
+ // The common part of the control packet header is processed
+ // in the parent. It is 4 bytes long.
+
+ i=4;
+ for (unsigned int j=0; j<this->chd_.count_; j++)
+ {
+ if (j==0)
+ {
+ ACE_NEW (this->chunk_,
+ sdesChunk_t);
+ cp = this->chunk_;
+
+ this->num_chunks_ = 1;
+ }
+ else
+ {
+ ACE_NEW (cp->next_,
+ sdesChunk_t);
+ cp = cp->next_;
+
+ this->num_chunks_++;
+ }
+ cp->next_ = 0;
+ cp->item_ = 0;
+ cp->ssrc_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+
+ while (buffer[i]!=RTCP_SDES_END)
+ {
+ if (!cp->item_)
+ {
+ ACE_NEW (cp->item_,
+ sdesItem_t);
+ ip = cp->item_;
+
+// this->num_items_ = 1;
+ }
+ else
+ {
+ ACE_NEW (ip->next_,
+ sdesItem_t);
+ ip = ip->next_;
+
+// this->num_items_++;
+ }
+ ip->next_ = 0;
+ ip->type_ = buffer[i];
+ i++;
+ if (ip->type_ != RTCP_SDES_PRIV)
+ {
+ ip->info_.standard_.length_ = buffer[i];
+ i++;
+ ACE_NEW (ip->info_.standard_.data_,
+ char[ip->info_.standard_.length_+1]);
+ memcpy(ip->info_.standard_.data_,
+ &buffer[i],
+ ip->info_.standard_.length_);
+ ip->info_.standard_.data_[ip->info_.standard_.length_] = 0;
+ i+=ip->info_.standard_.length_;
+ }
+ else
+ {
+ ip->info_.priv_.name_length_ = buffer[i];
+ i++;
+ ip->info_.priv_.data_length_ = buffer[i];
+ i++;
+ ACE_NEW (ip->info_.priv_.name_,
+ char[ip->info_.priv_.name_length_+1]);
+ memcpy(ip->info_.priv_.name_,
+ &buffer[i],
+ ip->info_.priv_.name_length_);
+ ip->info_.priv_.name_[ip->info_.priv_.name_length_] = 0;
+ i+=ip->info_.priv_.name_length_;
+ ACE_NEW (ip->info_.priv_.data_,
+ char[ip->info_.priv_.data_length_+1]);
+ memcpy(ip->info_.priv_.data_,
+ &buffer[i],
+ ip->info_.priv_.data_length_);
+ ip->info_.priv_.data_[ip->info_.priv_.data_length_] = 0;
+ i+=ip->info_.priv_.data_length_;
+ }
+ }
+ i++; // each chunk ends with a zero (END) item
+ // each chunk must end on an even 32 bit boundary
+ while (i%4) i++;
+ }
+
+ *len-=(this->chd_.length_+1)*4;
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SDES_Packet::~RTCP_SDES_Packet(void)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesChunk_t *cpprev;
+ sdesItem_t *ip; // pointer to item
+ sdesItem_t *ipprev;
+
+ cp = this->chunk_;
+ while (cp)
+ {
+ ip = cp->item_;
+ while (ip)
+ {
+ ipprev = ip;
+ ip = ip->next_;
+ if (ipprev->type_ != RTCP_SDES_PRIV)
+ {
+ delete []ipprev->info_.standard_.data_;
+ }
+ else
+ {
+ delete []ipprev->info_.priv_.name_;
+ delete []ipprev->info_.priv_.data_;
+ }
+
+ delete ipprev;
+ }
+ cpprev = cp;
+ cp = cp->next_;
+ delete cpprev;
+ }
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::add_chunk(ACE_UINT32 ssrc)
+{
+ sdesChunk_t *cp = 0; // pointer to chunk
+
+ // If this is the first chunk.
+ if (chd_.count_ == 0)
+ {
+ ACE_NEW (this->chunk_,
+ sdesChunk_t);
+ this->chunk_->next_ = 0;
+ this->chunk_->item_ = 0;
+ cp = this->chunk_;
+ }
+ else
+ {
+ cp = this->chunk_;
+ while (cp->next_)
+ cp = cp->next_;
+
+ ACE_NEW (cp->next_,
+ sdesChunk_t);
+ cp = cp->next_;
+ cp->next_ = 0;
+ cp->item_ = 0;
+ }
+ cp->ssrc_ = ssrc; // store the source
+ chd_.count_++; // increment the source count
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::add_item (ACE_UINT32 ssrc,
+ unsigned char type,
+ unsigned char length,
+ const char *data)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ if (this->chunk_ == 0)
+ {
+ this->add_chunk(ssrc);
+ }
+
+ cp = this->chunk_;
+
+ while (cp != 0)
+ {
+ if (cp->ssrc_ == ssrc)
+ {
+ break;
+ }
+
+ if (!cp->next_)
+ {
+ this->add_chunk(ssrc);
+ cp = cp->next_;
+ break;
+ }
+
+ cp = cp->next_;
+ }
+
+ ip = cp->item_;
+
+ if (ip == 0)
+ {
+ ACE_NEW (cp->item_,
+ sdesItem_t);
+
+ ip = cp->item_;
+ ip->next_= 0;
+ }
+ else
+ {
+ while (ip->next_)
+ {
+ ip = ip->next_;
+ }
+
+ ACE_NEW (ip->next_,
+ sdesItem_t);
+
+ ip = ip->next_;
+ ip->next_ = 0;
+ }
+
+ ip->type_ = type;
+
+ ip->info_.standard_.length_ = length;
+
+ ACE_NEW (ip->info_.standard_.data_,
+ char[length]);
+
+ memcpy(ip->info_.standard_.data_, data, length);
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::add_priv_item (ACE_UINT32 ssrc,
+ unsigned char nameLength,
+ const char* name,
+ unsigned char dataLength,
+ const char* data)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ if (this->chunk_ == 0)
+ {
+ this->add_chunk(ssrc);
+ }
+
+ cp = this->chunk_;
+
+ while (cp != 0)
+ {
+ if (cp->ssrc_ == ssrc)
+ {
+ break;
+ }
+
+ if (!cp->next_)
+ {
+ this->add_chunk(ssrc);
+ cp = cp->next_;
+ break;
+ }
+
+ cp = cp->next_;
+ }
+
+ ip = cp->item_;
+
+ if (ip == 0)
+ {
+ ACE_NEW (cp->item_,
+ sdesItem_t);
+
+ ip = cp->item_;
+ ip->next_ = 0;
+ }
+ else
+ {
+ while (ip->next_)
+ {
+ ip = ip->next_;
+ }
+
+ ACE_NEW (ip->next_,
+ sdesItem_t);
+
+ ip = ip->next_;
+ ip->next_ = 0;
+ }
+
+ ip->type_ = RTCP_SDES_PRIV;
+
+ ip->info_.priv_.name_length_ = nameLength;
+ ip->info_.priv_.data_length_ = dataLength;
+
+ ACE_NEW (ip->info_.priv_.name_,
+ char[nameLength]);
+
+ ACE_NEW (ip->info_.priv_.data_,
+ char[dataLength]);
+
+ memcpy(ip->info_.priv_.name_, name, nameLength);
+ memcpy(ip->info_.priv_.data_, data, dataLength);
+}
+
+//==============================================================================
+
+unsigned int
+RTCP_SDES_Packet::packet_size(void)
+{
+ int size;
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+
+ // Determine the size of the packet.
+ size = 4; // size of common header data in octets
+
+ cp = this->chunk_;
+ while (cp)
+ {
+ size += 4; // size of ssrc
+ ip = cp->item_;
+
+ while (ip && (ip->type_ != 0))
+ {
+ if (ip->type_ != RTCP_SDES_PRIV)
+ {
+ size += 2 + ip->info_.standard_.length_; // size of item
+ }
+ else
+ {
+ size += 3 + ip->info_.priv_.name_length_ + ip->info_.priv_.data_length_;
+ }
+ ip = ip->next_;
+ }
+ size += 4 - size%4; // pad with zeros to even 32 bit bound
+ cp = cp->next_;
+ }
+
+ chd_.length_ = static_cast<ACE_UINT16> (size/4 - 1);
+
+ return size;
+}
+
+//==============================================================================
+
+void
+RTCP_SDES_Packet::build_packet(void)
+{
+ sdesChunk_t *cp; // pointer to chunk
+ sdesItem_t *ip; // pointer to item
+ int index, i;
+
+ if (this->packet_data_)
+ delete this->packet_data_;
+
+ ACE_NEW (this->packet_data_,
+ char[this->packet_size()]);
+
+ index = 0;
+ this->packet_data_[index] = static_cast<char> ((chd_.ver_ << 6) |
+ (chd_.pad_ << 5) |
+ chd_.count_);
+ index++;
+ this->packet_data_[index] = chd_.pt_;
+ index++;
+ *((ACE_UINT16*)&this->packet_data_[index]) = htons(chd_.length_);
+ index+=2;
+
+ cp = this->chunk_;
+ while (cp)
+ {
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(cp->ssrc_);
+ index+=4;
+
+ ip = cp->item_;
+ while (ip && (ip->type_ != 0))
+ {
+ this->packet_data_[index] = ip->type_;
+ index++;
+ if (ip->type_ != RTCP_SDES_PRIV)
+ {
+ this->packet_data_[index] = ip->info_.standard_.length_;
+ index++;
+ for (i=0; i<ip->info_.standard_.length_; i++)
+ {
+ this->packet_data_[index] = ip->info_.standard_.data_[i];
+ index++;
+ }
+ }
+ else
+ {
+ this->packet_data_[index] = ip->info_.priv_.name_length_;
+ index++;
+ this->packet_data_[index] = ip->info_.priv_.data_length_;
+ index++;
+ for (i=0; i<ip->info_.priv_.name_length_; i++)
+ {
+ this->packet_data_[index] = ip->info_.priv_.name_[i];
+ index++;
+ }
+ for (i=0; i<ip->info_.priv_.data_length_; i++)
+ {
+ this->packet_data_[index] = ip->info_.priv_.data_[i];
+ index++;
+ }
+ }
+
+ ip = ip->next_;
+ }
+
+ this->packet_data_[index] = 0;
+ index++;
+
+ i=1;
+ while ((index)%4)
+ { // pad chunk with zeros to 32 bit bound
+ this->packet_data_[index] = 0;
+ index++;
+ i++;
+ }
+
+ // Store the number of bytes added. TODO: do we need this
+ // this->packet_data_[index - 1] = i;
+
+ cp = cp->next_;
+ }
+}
+
+void
+RTCP_SDES_Packet::dump (void)
+{
+ sdesItem_t *ip;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_SDES_Packet:: "));
+
+ if (this->num_chunks_ != 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Mixers not currently supported.\n"));
+ return;
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "from ssrc %u\n",
+ this->chunk_->ssrc_));
+
+ // Loop through all of the items.
+ ip = this->chunk_->item_;
+
+ while (ip)
+ {
+ // If there is no data to store, continue.
+ if (ip->info_.standard_.length_ == 0)
+ {
+ ip = ip->next_;
+ continue;
+ }
+
+ switch (ip->type_)
+ {
+ case RTCP_SDES_END:
+ break;
+ case RTCP_SDES_CNAME:
+ ACE_DEBUG ((LM_DEBUG,
+ " CNAME '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_NAME:
+ ACE_DEBUG ((LM_DEBUG,
+ " NAME '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_EMAIL:
+ ACE_DEBUG ((LM_DEBUG,
+ " EMAIL '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_PHONE:
+ ACE_DEBUG ((LM_DEBUG,
+ " PHONE '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_LOC:
+ ACE_DEBUG ((LM_DEBUG,
+ " LOC '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_TOOL:
+ ACE_DEBUG ((LM_DEBUG,
+ " TOOL '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_NOTE:
+ ACE_DEBUG ((LM_DEBUG,
+ " NOTE '%s'\n",
+ ip->info_.standard_.data_));
+ break;
+ case RTCP_SDES_PRIV:
+ ACE_DEBUG ((LM_DEBUG,
+ " '%s' '%s'\n",
+ ip->info_.priv_.name_,
+ ip->info_.priv_.data_));
+ break;
+ }
+ ip = ip->next_;
+ }
+
+}
+
+RTCP_SR_Packet::RTCP_SR_Packet(ACE_UINT32 ssrc,
+ ACE_UINT32 ntp_ts_msw,
+ ACE_UINT32 ntp_ts_lsw,
+ ACE_UINT32 timestamp,
+ ACE_UINT32 packets_sent,
+ ACE_UINT32 octets_sent,
+ RR_Block *blocks)
+{
+ RR_Block *block_ptr= 0;
+ chd_.count_ = 0;
+ chd_.ver_ = 2;
+ chd_.pt_ = RTCP_PT_SR;
+
+ this->ssrc_ = ssrc;
+ this->ntp_ts_msw_ = ntp_ts_msw;
+ this->ntp_ts_lsw_ = ntp_ts_lsw;
+ this->rtp_ts_ = timestamp;
+ this->psent_ = packets_sent;
+ this->osent_ = octets_sent;
+ this->rr_ = blocks;
+
+ block_ptr = blocks;
+
+ while (block_ptr)
+ {
+ 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_ = static_cast<ACE_UINT16> (6 + 6*(chd_.count_)); //+profile specific extensions ??
+
+ this->packet_data_ = 0;
+}
+
+//==============================================================================
+
+RTCP_SR_Packet::RTCP_SR_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;
+ this->ntp_ts_msw_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->ntp_ts_lsw_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->rtp_ts_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->psent_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ this->osent_ = ntohl(*(ACE_UINT32*)&buffer[i]);
+ i+=4;
+ for (unsigned int j=0; j<this->chd_.count_; j++)
+ {
+ if (j==0)
+ {
+ ACE_NEW (local_block_ptr,
+ RR_Block);
+ this->rr_ = local_block_ptr;
+ }
+ 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_SR_Packet::~RTCP_SR_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_SR_Packet::packet_size (void)
+{
+ ACE_UINT16 size = static_cast<ACE_UINT16> ((2+chd_.count_*6) * 4); // + profile specific extensions ?
+ size += 20; // the first line is the same as RR; 20 more bytes for SR
+
+ return size;
+}
+
+//==============================================================================
+
+void RTCP_SR_Packet::build_packet(void)
+{
+ int index = 0;
+ RR_Block *local_block_ptr;
+
+ if (this->packet_data_)
+ delete []this->packet_data_;
+
+ ACE_NEW (this->packet_data_,
+ char[this->packet_size()]);
+
+ this->packet_data_[index] = static_cast<char> ((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;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ssrc_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ntp_ts_msw_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->ntp_ts_lsw_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->rtp_ts_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->psent_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(this->osent_);
+ 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) &
+ local_block_ptr->lost_;
+ *((ACE_UINT32*)&this->packet_data_[index]) = temp;
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->last_seq_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->jitter_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->lsr_);
+ index+=4;
+ *((ACE_UINT32*)&this->packet_data_[index]) = htonl(local_block_ptr->dlsr_);
+ index+=4;
+ local_block_ptr = local_block_ptr->next_;
+ }
+}
+
+void
+RTCP_SR_Packet::dump (void)
+{
+ RR_Block *b = this->rr_;
+ int count = 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\nRTCP_SR_Packet:: from %u - %d rr blocks follow.\n",
+ this->ssrc_,
+ this->chd_.count_));
+ ACE_DEBUG ((LM_DEBUG,
+ " NTP(sec) %u.%u; RTP ts %u\n",
+ this->ntp_ts_msw_,
+ this->ntp_ts_lsw_,
+ this->rtp_ts_));
+ ACE_DEBUG ((LM_DEBUG,
+ " packets sent %u; octets sent %u\n",
+ this->psent_,
+ this->osent_));
+
+ while (b)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ " Block %d: ssrc %u; frac %u; lost %u; last seq %u\n",
+ count,
+ b->ssrc_,
+ b->fraction_,
+ b->lost_,
+ b->last_seq_));
+ ACE_DEBUG ((LM_DEBUG,
+ " jitter %u; lsr %u; dlsr %u;\n",
+ b->jitter_,
+ b->lsr_,
+ b->dlsr_));
+
+ b = b->next_;
+ ++count;
+ }
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL