RTCP_Packet.cpp

Go to the documentation of this file.
00001 // $Id: RTCP_Packet.cpp 78820 2007-07-07 20:06:46Z sowayaa $
00002 #include "orbsvcs/AV/RTCP_Packet.h"
00003 #include "orbsvcs/AV/RTP.h"
00004 
00005 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00006 
00007 RTCP_Packet::RTCP_Packet(void)
00008 {
00009   this->chd_.ver_ = 2;
00010   this->chd_.count_ = 0;
00011   this->chd_.pad_ = 0;
00012   this->chd_.length_ = 0;
00013   this->packet_data_ = 0;
00014 }
00015 
00016 RTCP_Packet::RTCP_Packet(char* buffer)
00017 {
00018   // Parse the common part of the control packet header.
00019   this->chd_.ver_ = (buffer[0] & 0xC0) >> 6;
00020 
00021   if (this->chd_.ver_ != RTP_VERSION)
00022     ACE_DEBUG ((LM_DEBUG,
00023                 "RTCP_Packet::RTCP_Packet version incorrect"));
00024 
00025   this->chd_.pad_ = (buffer[0] & 0x20) >> 5;
00026   this->chd_.count_ = buffer[0] & 0x1F;
00027   this->chd_.pt_ = buffer[1];
00028   this->chd_.length_ = ACE_NTOHS(*(ACE_UINT16*)&buffer[2]);
00029   this->packet_data_ = 0;
00030 }
00031 
00032 RTCP_Packet::~RTCP_Packet(void)
00033 {
00034 }
00035 
00036 void
00037 RTCP_Packet::get_packet_data(char **buffer, ACE_UINT16 &length)
00038 {
00039   length = static_cast<ACE_UINT16> (this->packet_size());
00040 
00041   // buiidPacket is defined for each child of RTCP_Packet
00042   // buildPacket creates a snapshot of the RTCP packet in the buffer pktData
00043   this->build_packet ();
00044 
00045   *buffer = this->packet_data_;
00046 }
00047 
00048 int
00049 RTCP_Packet::is_valid (char is_first)
00050 {
00051   // make sure the RTP version is correct
00052   if (this->chd_.ver_ != RTP_VERSION)
00053     return 0;
00054 
00055   // these checks are only for the first RTCP packet in a compound packet
00056   if (is_first)
00057     {
00058       // the payload type must be RR or SR
00059       if ((this->chd_.pt_ != RTCP_PT_SR) && (this->chd_.pt_ != RTCP_PT_RR))
00060         return 0;
00061 
00062       // the padding bit must not be set
00063       if (this->chd_.pad_ != 0)
00064         return 0;
00065     }
00066 
00067   return 1;
00068 
00069 }
00070 
00071 /*
00072  * RTCP_BYE_Packet
00073  */
00074 
00075 RTCP_BYE_Packet::RTCP_BYE_Packet(ACE_UINT32 *ssrc_list,
00076                                  unsigned char length,
00077                                  const char *text)
00078 {
00079   this->chd_.ver_ = 2;
00080   this->chd_.count_ = length;
00081   this->chd_.pt_ = RTCP_PT_BYE;
00082 
00083   if (length)
00084     {
00085       ACE_NEW (this->ssrc_list_,
00086                ACE_UINT32[length]);
00087 
00088       this->ssrc_list_length_ = length;
00089 
00090       for (int i=0; i<length; i++)
00091         this->ssrc_list_[i] = ssrc_list[i];
00092     }
00093 
00094   // Optional - if there is a reason for leaving, store it.
00095   // The reason is padded with extra zeros because the packet must
00096   // end on an even 32-bit boundary.
00097   ACE_OS::memset(this->reason_, 0, sizeof(this->reason_));
00098   if (text)
00099     {
00100       size_t text_length = ACE_OS::strlen(text);
00101       ACE_OS::memcpy(this->reason_, text, text_length);
00102       this->reason_length_ = static_cast<unsigned char> (text_length);
00103     }
00104   else
00105     this->reason_length_ = 0;
00106 
00107   // Set the packet length
00108   this->chd_.length_ = static_cast<ACE_UINT16> (this->chd_.count_ + (this->reason_length_+1)/4);
00109   if ((this->reason_length_+1)%4)
00110     this->chd_.length_++;
00111 
00112   this->packet_data_ = 0;
00113 }
00114 
00115 //==============================================================================
00116 
00117 RTCP_BYE_Packet::RTCP_BYE_Packet(char* buffer, int *len)
00118                  : RTCP_Packet(buffer)
00119 {
00120   unsigned int index = 0;
00121   unsigned int j;
00122 
00123   // The common part of the header is initialized in the parent.
00124   index=4;
00125 
00126   ACE_NEW (this->ssrc_list_,
00127            ACE_UINT32[this->chd_.count_]);
00128   this->ssrc_list_length_ = this->chd_.count_;
00129 
00130   // Store the source ids of the sources leaving the session
00131   for (j=0; j<this->chd_.count_; j++)
00132     {
00133       this->ssrc_list_[j] = ACE_NTOHL(*(ACE_UINT32*)&buffer[index]);
00134       index+=4;
00135     }
00136 
00137   // Optional - store the reason for leaving
00138   unsigned int temp = this->chd_.length_; // Borland reports a warning on the
00139                                           // following line with out this.
00140   ACE_OS::memset(this->reason_, 0, sizeof(this->reason_));
00141   if (temp > this->chd_.count_)
00142     {
00143       this->reason_length_ = buffer[index];
00144       index++;
00145       ACE_OS::memcpy(this->reason_, &buffer[index], this->reason_length_);
00146       index+=this->reason_length_;
00147 
00148     }
00149   else
00150     this->reason_length_ = 0;
00151 
00152   // Decrement the length by the size of this message. This is necessary
00153   // because multiple RTCP packets may be contained in a single UDP packet.
00154   *len-=(chd_.length_+1)*4;
00155 
00156   this->packet_data_ = 0;
00157 }
00158 
00159 //==============================================================================
00160 
00161 RTCP_BYE_Packet::~RTCP_BYE_Packet(void)
00162 {
00163   if (this->ssrc_list_)
00164     delete []this->ssrc_list_;
00165   if (this->packet_data_)
00166     delete []this->packet_data_;
00167 }
00168 
00169 //==============================================================================
00170 
00171 unsigned int
00172 RTCP_BYE_Packet::packet_size(void)
00173 {
00174   ACE_UINT16 size = static_cast<ACE_UINT16> ((1+chd_.count_) * 4);
00175 
00176   if (this->reason_length_ > 0)
00177     {
00178       size += this->reason_length_ + 1;
00179       if (size%4)
00180         size += 4 - size%4; // pad with zeros to even 32 bit bound
00181     }
00182 
00183   return size;
00184 }
00185 
00186 //==============================================================================
00187 
00188 void
00189 RTCP_BYE_Packet::ssrc_list(ACE_UINT32 **ssrc_list, unsigned char &length)
00190 {
00191   *ssrc_list = this->ssrc_list_;
00192   length = this->ssrc_list_length_;
00193 }
00194 
00195 //==============================================================================
00196 
00197 const char *
00198 RTCP_BYE_Packet::reason (void)
00199 {
00200   ACE_CString reason = (const char *)this->reason_;
00201 
00202   return reason.c_str();
00203 }
00204 
00205 //==============================================================================
00206 
00207 void
00208 RTCP_BYE_Packet::build_packet(void)
00209 {
00210   unsigned int index;
00211   unsigned int i;
00212 
00213   if (this->packet_data_)
00214     delete []this->packet_data_;
00215 
00216   ACE_NEW (this->packet_data_,
00217            char[this->packet_size()]);
00218 
00219   index = 0;
00220   this->packet_data_[index] = static_cast<char> ((this->chd_.ver_ << 6) |
00221                                                  (this->chd_.pad_ << 5) |
00222                                                  this->chd_.count_);
00223   index++;
00224   this->packet_data_[index] = this->chd_.pt_;
00225   index++;
00226   *((ACE_UINT16*)&this->packet_data_[index]) = ACE_HTONS(this->chd_.length_);
00227   index+=2;
00228 
00229   for (i=0; i<this->chd_.count_; i++)
00230     {
00231       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->ssrc_list_[i]);
00232       index+=4;
00233     }
00234 
00235   if (this->reason_)
00236     {
00237       this->packet_data_[index] = this->reason_length_;
00238       index++;
00239       ACE_OS::memcpy(&this->packet_data_[index], this->reason_, this->reason_length_);
00240       index += this->reason_length_;
00241       while (index < this->packet_size())
00242         {
00243           this->packet_data_[index] = 0;
00244           index ++;
00245         }
00246     }
00247 }
00248 
00249 void
00250 RTCP_BYE_Packet::dump (void)
00251 {
00252   ACE_DEBUG ((LM_DEBUG,
00253               "\nRTCP_BYE_Packet:: from ssrc(s) "));
00254   for (int i=0; i< this->ssrc_list_length_; i++)
00255     ACE_DEBUG ((LM_DEBUG,
00256                 "%u ",
00257                 this->ssrc_list_[i]));
00258   ACE_DEBUG ((LM_DEBUG,
00259               "\n    Reason '%s'\n",
00260               this->reason_));
00261 }
00262 
00263 RTCP_RR_Packet::RTCP_RR_Packet(ACE_UINT32 ssrc, RR_Block *blocks)
00264 {
00265   RR_Block *block_ptr = blocks;
00266 
00267   this->chd_.count_ = 0;
00268   this->chd_.ver_ = 2;
00269   this->chd_.pt_ = RTCP_PT_RR;
00270   this->ssrc_ = ssrc;
00271   this->rr_ = blocks;
00272 
00273   while (block_ptr)
00274     {
00275       this->chd_.count_++;
00276 
00277       // Can only have 31 receiver reports
00278       if (this->chd_.count_ == 31)
00279         {
00280           block_ptr->next_ = 0;
00281           break;
00282         }
00283 
00284       block_ptr = block_ptr->next_;
00285     }
00286 
00287   this->chd_.length_ = static_cast<ACE_UINT16> (1+6*(this->chd_.count_)); // + profile specific extensions ??
00288 
00289   this->packet_data_ = 0;
00290 }
00291 
00292 //==============================================================================
00293 
00294 RTCP_RR_Packet::RTCP_RR_Packet (char* buffer,
00295                                 int *len)
00296   :RTCP_Packet (buffer)
00297 {
00298   unsigned int i = 0;
00299   RR_Block *local_block_ptr = 0;
00300 
00301   this->rr_ = 0;
00302 
00303   // The common part of the header is initialized in the parent.
00304   i=4;
00305   this->ssrc_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00306   i+=4;
00307   for (unsigned int j=0; j<this->chd_.count_; j++)
00308     {
00309       if (j==0)
00310         {
00311           ACE_NEW (this->rr_,
00312                    RR_Block);
00313           local_block_ptr = this->rr_;
00314         }
00315       else
00316         {
00317           ACE_NEW (local_block_ptr->next_,
00318                    RR_Block);
00319           local_block_ptr = local_block_ptr->next_;
00320         }
00321 
00322       local_block_ptr->next_ = 0;
00323       local_block_ptr->ssrc_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00324       i+=4;
00325       ACE_UINT32 temp = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00326       local_block_ptr->fraction_ = (temp&0xff000000) >> 24;
00327       local_block_ptr->lost_ = temp & 0x00ffffff;
00328       i+=4;
00329       local_block_ptr->last_seq_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00330       i+=4;
00331       local_block_ptr->jitter_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00332       i+=4;
00333       local_block_ptr->lsr_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00334       i+=4;
00335       local_block_ptr->dlsr_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00336       i+=4;
00337     }
00338 
00339   *len-=(this->chd_.length_+1)*4;
00340 
00341   this->packet_data_ = 0;
00342 }
00343 
00344 //==============================================================================
00345 
00346 RTCP_RR_Packet::~RTCP_RR_Packet(void)
00347 {
00348   RR_Block *prev;
00349 
00350   if (this->rr_)
00351     {
00352       while (this->rr_)
00353         {
00354           prev = this->rr_;
00355           this->rr_ = this->rr_->next_;
00356           delete prev;
00357         }
00358     }
00359 
00360   if (this->packet_data_)
00361     delete []this->packet_data_;
00362 }
00363 
00364 //==============================================================================
00365 
00366 unsigned int
00367 RTCP_RR_Packet::packet_size(void)
00368 {
00369     ACE_UINT16 size = static_cast<ACE_UINT16> ((2+this->chd_.count_*6) * 4);
00370     return size;
00371 }
00372 
00373 //==============================================================================
00374 
00375 void
00376 RTCP_RR_Packet::build_packet(void)
00377 {
00378   int index;
00379   RR_Block *local_block_ptr;
00380 
00381   if (this->packet_data_)
00382     delete []this->packet_data_;
00383 
00384   ACE_NEW (this->packet_data_,
00385            char [this->packet_size ()]);
00386 
00387   index = 0;
00388   this->packet_data_[index] = static_cast<char> ((this->chd_.ver_ << 6) |
00389                                                  (this->chd_.pad_ << 5) |
00390                                                  this->chd_.count_);
00391   index++;
00392   this->packet_data_[index] = chd_.pt_;
00393   index++;
00394   *((ACE_UINT16*)&this->packet_data_[index]) = ACE_HTONS(chd_.length_);
00395   index+=2;
00396   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->ssrc_);
00397   index+=4;
00398 
00399   local_block_ptr = this->rr_;
00400   while (local_block_ptr)
00401     {
00402       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->ssrc_);
00403       index+=4;
00404       ACE_UINT32 temp = ACE_HTONL((local_block_ptr->fraction_&0xff) << 24) &
00405                               local_block_ptr->lost_;
00406       *((ACE_UINT32*)&this->packet_data_[index]) = temp;
00407       index+=4;
00408       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->last_seq_);
00409       index+=4;
00410       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->jitter_);
00411       index+=4;
00412       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->lsr_);
00413       index+=4;
00414       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->dlsr_);
00415       index+=4;
00416       local_block_ptr = local_block_ptr->next_;
00417     }
00418 }
00419 
00420 void
00421 RTCP_RR_Packet::dump (void)
00422 {
00423   RR_Block *b = this->rr_;
00424   int count = 1;
00425 
00426   ACE_DEBUG ((LM_DEBUG,
00427               "\nRTCP_RR_Packet:: from %u - %d rr blocks follow.\n",
00428               this->ssrc_,
00429               this->chd_.count_));
00430 
00431   while (b)
00432     {
00433       ACE_DEBUG ((LM_DEBUG,
00434                   "  Block %d: ssrc %u; frac %u; lost %u; last seq %u\n",
00435                   count,
00436                   b->ssrc_,
00437                   b->fraction_,
00438                   b->lost_,
00439                   b->last_seq_));
00440       ACE_DEBUG ((LM_DEBUG,
00441                   "           jitter %u; lsr %u; dlsr %u;\n",
00442                   b->jitter_,
00443                   b->lsr_,
00444                   b->dlsr_));
00445 
00446       b = b->next_;
00447       ++count;
00448     }
00449 }
00450 
00451 
00452 RTCP_SDES_Packet::RTCP_SDES_Packet(void) :
00453                    RTCP_Packet ()
00454 {
00455   this->chd_.pt_ = RTCP_PT_SDES;
00456   this->chunk_ = 0;
00457   this->packet_data_ = 0;
00458   this->num_chunks_ = 0;
00459 //  this->num_items_ = 0;
00460 }
00461 
00462 //==============================================================================
00463 
00464 RTCP_SDES_Packet::RTCP_SDES_Packet(char* buffer, int *len):
00465                    RTCP_Packet (buffer)
00466 {
00467   unsigned int i;
00468   sdesChunk_t *cp = 0; // pointer to chunk
00469   sdesItem_t *ip = 0; // pointer to item
00470 
00471   // The common part of the control packet header is processed
00472   // in the parent. It is 4 bytes long.
00473 
00474   i=4;
00475   for (unsigned int j=0; j<this->chd_.count_; j++)
00476     {
00477       if (j==0)
00478         {
00479           ACE_NEW (this->chunk_,
00480                    sdesChunk_t);
00481           cp = this->chunk_;
00482 
00483           this->num_chunks_ = 1;
00484         }
00485       else
00486         {
00487           ACE_NEW (cp->next_,
00488                    sdesChunk_t);
00489           cp = cp->next_;
00490 
00491           this->num_chunks_++;
00492         }
00493       cp->next_ = 0;
00494       cp->item_ = 0;
00495       cp->ssrc_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
00496       i+=4;
00497 
00498       while (buffer[i]!=RTCP_SDES_END)
00499         {
00500           if (!cp->item_)
00501             {
00502               ACE_NEW (cp->item_,
00503                        sdesItem_t);
00504               ip = cp->item_;
00505 
00506 //              this->num_items_ = 1;
00507             }
00508           else
00509             {
00510               ACE_NEW (ip->next_,
00511                        sdesItem_t);
00512               ip = ip->next_;
00513 
00514 //              this->num_items_++;
00515             }
00516           ip->next_ = 0;
00517           ip->type_ = buffer[i];
00518           i++;
00519           if (ip->type_ != RTCP_SDES_PRIV)
00520             {
00521               ip->info_.standard_.length_ = buffer[i];
00522               i++;
00523               ACE_NEW (ip->info_.standard_.data_,
00524                        char[ip->info_.standard_.length_+1]);
00525               ACE_OS::memcpy(ip->info_.standard_.data_,
00526                              &buffer[i],
00527                              ip->info_.standard_.length_);
00528               ip->info_.standard_.data_[ip->info_.standard_.length_] = 0;
00529               i+=ip->info_.standard_.length_;
00530             }
00531           else
00532             {
00533               ip->info_.priv_.name_length_ = buffer[i];
00534               i++;
00535               ip->info_.priv_.data_length_ = buffer[i];
00536               i++;
00537               ACE_NEW (ip->info_.priv_.name_,
00538                        char[ip->info_.priv_.name_length_+1]);
00539               ACE_OS::memcpy(ip->info_.priv_.name_,
00540                              &buffer[i],
00541                              ip->info_.priv_.name_length_);
00542               ip->info_.priv_.name_[ip->info_.priv_.name_length_] = 0;
00543               i+=ip->info_.priv_.name_length_;
00544               ACE_NEW (ip->info_.priv_.data_,
00545                        char[ip->info_.priv_.data_length_+1]);
00546               ACE_OS::memcpy(ip->info_.priv_.data_,
00547                              &buffer[i],
00548                              ip->info_.priv_.data_length_);
00549               ip->info_.priv_.data_[ip->info_.priv_.data_length_] = 0;
00550               i+=ip->info_.priv_.data_length_;
00551             }
00552         }
00553         i++; // each chunk ends with a zero (END) item
00554         // each chunk must end on an even 32 bit boundary
00555         while (i%4) i++;
00556     }
00557 
00558   *len-=(this->chd_.length_+1)*4;
00559 
00560   this->packet_data_ = 0;
00561 }
00562 
00563 //==============================================================================
00564 
00565 RTCP_SDES_Packet::~RTCP_SDES_Packet(void)
00566 {
00567   sdesChunk_t *cp; // pointer to chunk
00568   sdesChunk_t *cpprev;
00569   sdesItem_t *ip; // pointer to item
00570   sdesItem_t *ipprev;
00571 
00572   cp = this->chunk_;
00573   while (cp)
00574     {
00575       ip = cp->item_;
00576       while (ip)
00577         {
00578           ipprev = ip;
00579           ip = ip->next_;
00580           if (ipprev->type_ != RTCP_SDES_PRIV)
00581             {
00582               delete []ipprev->info_.standard_.data_;
00583             }
00584           else
00585             {
00586               delete []ipprev->info_.priv_.name_;
00587               delete []ipprev->info_.priv_.data_;
00588             }
00589 
00590           delete ipprev;
00591         }
00592       cpprev = cp;
00593       cp = cp->next_;
00594       delete cpprev;
00595     }
00596 
00597   if (this->packet_data_)
00598     delete []this->packet_data_;
00599 }
00600 
00601 //==============================================================================
00602 
00603 void
00604 RTCP_SDES_Packet::add_chunk(ACE_UINT32 ssrc)
00605 {
00606   sdesChunk_t *cp = 0; // pointer to chunk
00607 
00608   // If this is the first chunk.
00609   if (chd_.count_ == 0)
00610     {
00611       ACE_NEW (this->chunk_,
00612                sdesChunk_t);
00613       this->chunk_->next_ = 0;
00614       this->chunk_->item_ = 0;
00615       cp = this->chunk_;
00616     }
00617   else
00618     {
00619       cp = this->chunk_;
00620       while (cp->next_)
00621         cp = cp->next_;
00622 
00623       ACE_NEW (cp->next_,
00624                sdesChunk_t);
00625       cp = cp->next_;
00626       cp->next_ = 0;
00627       cp->item_ = 0;
00628     }
00629   cp->ssrc_ = ssrc;    // store the source
00630   chd_.count_++;       // increment the source count
00631 }
00632 
00633 //==============================================================================
00634 
00635 void
00636 RTCP_SDES_Packet::add_item (ACE_UINT32 ssrc,
00637                             unsigned char type,
00638                             unsigned char length,
00639                             const char *data)
00640 {
00641   sdesChunk_t *cp; // pointer to chunk
00642   sdesItem_t *ip; // pointer to item
00643 
00644   if (this->chunk_ == 0)
00645     {
00646       this->add_chunk(ssrc);
00647     }
00648 
00649   cp = this->chunk_;
00650 
00651   while (cp != 0)
00652     {
00653       if (cp->ssrc_ == ssrc)
00654         {
00655           break;
00656         }
00657 
00658       if (!cp->next_)
00659         {
00660           this->add_chunk(ssrc);
00661           cp = cp->next_;
00662           break;
00663         }
00664 
00665       cp = cp->next_;
00666     }
00667 
00668   ip = cp->item_;
00669 
00670   if (ip == 0)
00671     {
00672       ACE_NEW (cp->item_,
00673                sdesItem_t);
00674 
00675       ip = cp->item_;
00676       ip->next_= 0;
00677     }
00678   else
00679     {
00680       while (ip->next_)
00681         {
00682           ip = ip->next_;
00683         }
00684 
00685       ACE_NEW (ip->next_,
00686                sdesItem_t);
00687 
00688       ip = ip->next_;
00689       ip->next_ = 0;
00690     }
00691 
00692   ip->type_ = type;
00693 
00694   ip->info_.standard_.length_ = length;
00695 
00696   ACE_NEW (ip->info_.standard_.data_,
00697            char[length]);
00698 
00699   ACE_OS::memcpy(ip->info_.standard_.data_, data, length);
00700 }
00701 
00702 //==============================================================================
00703 
00704 void
00705 RTCP_SDES_Packet::add_priv_item (ACE_UINT32 ssrc,
00706                                  unsigned char nameLength,
00707                                  const char* name,
00708                                  unsigned char dataLength,
00709                                  const char* data)
00710 {
00711   sdesChunk_t *cp; // pointer to chunk
00712   sdesItem_t *ip; // pointer to item
00713 
00714   if (this->chunk_ == 0)
00715     {
00716       this->add_chunk(ssrc);
00717     }
00718 
00719   cp = this->chunk_;
00720 
00721   while (cp != 0)
00722     {
00723       if (cp->ssrc_ == ssrc)
00724         {
00725           break;
00726         }
00727 
00728       if (!cp->next_)
00729         {
00730           this->add_chunk(ssrc);
00731           cp = cp->next_;
00732           break;
00733         }
00734 
00735       cp = cp->next_;
00736     }
00737 
00738   ip = cp->item_;
00739 
00740   if (ip == 0)
00741     {
00742       ACE_NEW (cp->item_,
00743                sdesItem_t);
00744 
00745       ip = cp->item_;
00746       ip->next_ = 0;
00747     }
00748   else
00749     {
00750       while (ip->next_)
00751         {
00752           ip = ip->next_;
00753         }
00754 
00755       ACE_NEW (ip->next_,
00756                sdesItem_t);
00757 
00758       ip = ip->next_;
00759       ip->next_ = 0;
00760     }
00761 
00762   ip->type_ = RTCP_SDES_PRIV;
00763 
00764   ip->info_.priv_.name_length_ = nameLength;
00765   ip->info_.priv_.data_length_ = dataLength;
00766 
00767   ACE_NEW (ip->info_.priv_.name_,
00768            char[nameLength]);
00769 
00770   ACE_NEW (ip->info_.priv_.data_,
00771            char[dataLength]);
00772 
00773   ACE_OS::memcpy(ip->info_.priv_.name_, name, nameLength);
00774   ACE_OS::memcpy(ip->info_.priv_.data_, data, dataLength);
00775 }
00776 
00777 //==============================================================================
00778 
00779 unsigned int
00780 RTCP_SDES_Packet::packet_size(void)
00781 {
00782   int size;
00783   sdesChunk_t *cp; // pointer to chunk
00784   sdesItem_t *ip; // pointer to item
00785 
00786   // Determine the size of the packet.
00787   size = 4;  // size of common header data in octets
00788 
00789   cp = this->chunk_;
00790   while (cp)
00791     {
00792       size += 4; // size of ssrc
00793       ip = cp->item_;
00794 
00795       while (ip && (ip->type_ != 0))
00796         {
00797           if (ip->type_ != RTCP_SDES_PRIV)
00798             {
00799               size += 2 + ip->info_.standard_.length_;  // size of item
00800             }
00801           else
00802             {
00803               size += 3 + ip->info_.priv_.name_length_ + ip->info_.priv_.data_length_;
00804             }
00805           ip = ip->next_;
00806         }
00807       size += 4 - size%4;           // pad with zeros to even 32 bit bound
00808       cp = cp->next_;
00809     }
00810 
00811   chd_.length_ = static_cast<ACE_UINT16> (size/4 - 1);
00812 
00813   return size;
00814 }
00815 
00816 //==============================================================================
00817 
00818 void
00819 RTCP_SDES_Packet::build_packet(void)
00820 {
00821   sdesChunk_t *cp; // pointer to chunk
00822   sdesItem_t *ip; // pointer to item
00823   int index, i;
00824 
00825   if (this->packet_data_)
00826     delete this->packet_data_;
00827 
00828   ACE_NEW (this->packet_data_,
00829            char[this->packet_size()]);
00830 
00831   index = 0;
00832   this->packet_data_[index] = static_cast<char> ((chd_.ver_ << 6) |
00833                                                  (chd_.pad_ << 5) |
00834                                      chd_.count_);
00835   index++;
00836   this->packet_data_[index] = chd_.pt_;
00837   index++;
00838   *((ACE_UINT16*)&this->packet_data_[index]) = ACE_HTONS(chd_.length_);
00839   index+=2;
00840 
00841   cp = this->chunk_;
00842   while (cp)
00843     {
00844       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(cp->ssrc_);
00845       index+=4;
00846 
00847       ip = cp->item_;
00848       while (ip && (ip->type_ != 0))
00849         {
00850           this->packet_data_[index] = ip->type_;
00851           index++;
00852           if (ip->type_ != RTCP_SDES_PRIV)
00853             {
00854               this->packet_data_[index] = ip->info_.standard_.length_;
00855               index++;
00856               for (i=0; i<ip->info_.standard_.length_; i++)
00857                 {
00858                   this->packet_data_[index] = ip->info_.standard_.data_[i];
00859                   index++;
00860                 }
00861             }
00862           else
00863             {
00864               this->packet_data_[index] = ip->info_.priv_.name_length_;
00865               index++;
00866               this->packet_data_[index] = ip->info_.priv_.data_length_;
00867               index++;
00868               for (i=0; i<ip->info_.priv_.name_length_; i++)
00869                 {
00870                   this->packet_data_[index] = ip->info_.priv_.name_[i];
00871                   index++;
00872                 }
00873               for (i=0; i<ip->info_.priv_.data_length_; i++)
00874                 {
00875                   this->packet_data_[index] = ip->info_.priv_.data_[i];
00876                   index++;
00877                 }
00878             }
00879 
00880           ip = ip->next_;
00881         }
00882 
00883       this->packet_data_[index] = 0;
00884       index++;
00885 
00886       i=1;
00887       while ((index)%4)
00888         { // pad chunk with zeros to 32 bit bound
00889           this->packet_data_[index] = 0;
00890           index++;
00891           i++;
00892         }
00893 
00894       // Store the number of bytes added. TODO: do we need this
00895       // this->packet_data_[index - 1] = i;
00896 
00897       cp = cp->next_;
00898     }
00899 }
00900 
00901 void
00902 RTCP_SDES_Packet::dump (void)
00903 {
00904   sdesItem_t *ip;
00905 
00906   ACE_DEBUG ((LM_DEBUG,
00907               "\nRTCP_SDES_Packet:: "));
00908 
00909   if (this->num_chunks_ != 1)
00910     {
00911       ACE_DEBUG ((LM_DEBUG,
00912                   "Mixers not currently supported.\n"));
00913       return;
00914     }
00915 
00916   ACE_DEBUG ((LM_DEBUG,
00917               "from ssrc %u\n",
00918               this->chunk_->ssrc_));
00919 
00920   // Loop through all of the items.
00921   ip = this->chunk_->item_;
00922 
00923   while (ip)
00924     {
00925       // If there is no data to store, continue.
00926       if (ip->info_.standard_.length_ == 0)
00927         {
00928           ip = ip->next_;
00929           continue;
00930         }
00931 
00932       switch (ip->type_)
00933       {
00934         case RTCP_SDES_END:
00935              break;
00936         case RTCP_SDES_CNAME:
00937              ACE_DEBUG ((LM_DEBUG,
00938                          "    CNAME '%s'\n",
00939                          ip->info_.standard_.data_));
00940              break;
00941         case RTCP_SDES_NAME:
00942              ACE_DEBUG ((LM_DEBUG,
00943                          "    NAME '%s'\n",
00944                          ip->info_.standard_.data_));
00945              break;
00946         case RTCP_SDES_EMAIL:
00947              ACE_DEBUG ((LM_DEBUG,
00948                          "    EMAIL '%s'\n",
00949                          ip->info_.standard_.data_));
00950              break;
00951         case RTCP_SDES_PHONE:
00952              ACE_DEBUG ((LM_DEBUG,
00953                          "    PHONE '%s'\n",
00954                          ip->info_.standard_.data_));
00955              break;
00956         case RTCP_SDES_LOC:
00957              ACE_DEBUG ((LM_DEBUG,
00958                          "    LOC '%s'\n",
00959                          ip->info_.standard_.data_));
00960              break;
00961         case RTCP_SDES_TOOL:
00962              ACE_DEBUG ((LM_DEBUG,
00963                          "    TOOL '%s'\n",
00964                          ip->info_.standard_.data_));
00965              break;
00966         case RTCP_SDES_NOTE:
00967              ACE_DEBUG ((LM_DEBUG,
00968                          "    NOTE '%s'\n",
00969                          ip->info_.standard_.data_));
00970              break;
00971         case RTCP_SDES_PRIV:
00972              ACE_DEBUG ((LM_DEBUG,
00973                          "    '%s' '%s'\n",
00974                          ip->info_.priv_.name_,
00975                          ip->info_.priv_.data_));
00976              break;
00977       }
00978       ip = ip->next_;
00979     }
00980 
00981 }
00982 
00983 RTCP_SR_Packet::RTCP_SR_Packet(ACE_UINT32 ssrc,
00984                                ACE_UINT32 ntp_ts_msw,
00985                                ACE_UINT32 ntp_ts_lsw,
00986                                ACE_UINT32 timestamp,
00987                                ACE_UINT32 packets_sent,
00988                                ACE_UINT32 octets_sent,
00989                                RR_Block *blocks)
00990 {
00991   RR_Block *block_ptr= 0;
00992   chd_.count_ = 0;
00993   chd_.ver_ = 2;
00994   chd_.pt_ = RTCP_PT_SR;
00995 
00996   this->ssrc_ = ssrc;
00997   this->ntp_ts_msw_ = ntp_ts_msw;
00998   this->ntp_ts_lsw_ = ntp_ts_lsw;
00999   this->rtp_ts_ = timestamp;
01000   this->psent_ = packets_sent;
01001   this->osent_ = octets_sent;
01002   this->rr_ = blocks;
01003 
01004   block_ptr = blocks;
01005 
01006   while (block_ptr)
01007     {
01008       chd_.count_++;
01009 
01010       // Can only have 31 receiver reports
01011       if (this->chd_.count_ == 31)
01012         {
01013           block_ptr->next_ = 0;
01014           break;
01015         }
01016 
01017       block_ptr = block_ptr->next_;
01018     }
01019 
01020   this->chd_.length_ = static_cast<ACE_UINT16> (6 + 6*(chd_.count_)); //+profile specific extensions ??
01021 
01022   this->packet_data_ = 0;
01023 }
01024 
01025 //==============================================================================
01026 
01027 RTCP_SR_Packet::RTCP_SR_Packet (char* buffer,
01028                                 int *len)
01029                 : RTCP_Packet (buffer)
01030 {
01031   unsigned int i = 0;
01032   RR_Block *local_block_ptr = 0;
01033 
01034   this->rr_ = 0;
01035 
01036   // The common part of the header is initialized in the parent.
01037   i=4;
01038   this->ssrc_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01039   i+=4;
01040   this->ntp_ts_msw_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01041   i+=4;
01042   this->ntp_ts_lsw_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01043   i+=4;
01044   this->rtp_ts_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01045   i+=4;
01046   this->psent_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01047   i+=4;
01048   this->osent_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01049   i+=4;
01050   for (unsigned int j=0; j<this->chd_.count_; j++)
01051     {
01052       if (j==0)
01053         {
01054           ACE_NEW (local_block_ptr,
01055                    RR_Block);
01056           this->rr_ = local_block_ptr;
01057         }
01058       else
01059         {
01060           ACE_NEW (local_block_ptr->next_,
01061                    RR_Block);
01062           local_block_ptr = local_block_ptr->next_;
01063         }
01064 
01065       local_block_ptr->next_ = 0;
01066       local_block_ptr->ssrc_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01067       i+=4;
01068       ACE_UINT32 temp = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01069       local_block_ptr->fraction_ = (temp&0xff000000) >> 24;
01070       local_block_ptr->lost_ = temp & 0x00ffffff;
01071       i+=4;
01072       local_block_ptr->last_seq_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01073       i+=4;
01074       local_block_ptr->jitter_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01075       i+=4;
01076       local_block_ptr->lsr_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01077       i+=4;
01078       local_block_ptr->dlsr_ = ACE_NTOHL(*(ACE_UINT32*)&buffer[i]);
01079       i+=4;
01080     }
01081 
01082   *len-=(this->chd_.length_+1)*4;
01083 
01084   this->packet_data_ = 0;
01085 }
01086 
01087 //==============================================================================
01088 
01089 RTCP_SR_Packet::~RTCP_SR_Packet(void)
01090 {
01091   RR_Block *prev;
01092 
01093   if (this->rr_)
01094     {
01095       while (this->rr_)
01096         {
01097           prev = this->rr_;
01098           this->rr_ = this->rr_->next_;
01099           delete prev;
01100         }
01101     }
01102 
01103   if (this->packet_data_)
01104     delete []this->packet_data_;
01105 }
01106 
01107 //==============================================================================
01108 
01109 unsigned int RTCP_SR_Packet::packet_size (void)
01110 {
01111   ACE_UINT16 size  = static_cast<ACE_UINT16> ((2+chd_.count_*6) * 4); // + profile specific extensions ?
01112   size += 20; // the first line is the same as RR; 20 more bytes for SR
01113 
01114   return size;
01115 }
01116 
01117 //==============================================================================
01118 
01119 void RTCP_SR_Packet::build_packet(void)
01120 {
01121   int index = 0;
01122   RR_Block *local_block_ptr;
01123 
01124   if (this->packet_data_)
01125     delete []this->packet_data_;
01126 
01127   ACE_NEW (this->packet_data_,
01128            char[this->packet_size()]);
01129 
01130   this->packet_data_[index] = static_cast<char> ((this->chd_.ver_ << 6) |
01131                                                  (this->chd_.pad_ << 5) | 
01132                                       this->chd_.count_);
01133   index++;
01134   this->packet_data_[index] = this->chd_.pt_;
01135   index++;
01136   *((ACE_UINT16*)&this->packet_data_[index]) = ACE_HTONS(this->chd_.length_);
01137   index+=2;
01138   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->ssrc_);
01139   index+=4;
01140   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->ntp_ts_msw_);
01141   index+=4;
01142   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->ntp_ts_lsw_);
01143   index+=4;
01144   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->rtp_ts_);
01145   index+=4;
01146   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->psent_);
01147   index+=4;
01148   *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(this->osent_);
01149   index+=4;
01150 
01151   local_block_ptr = this->rr_;
01152   while (local_block_ptr)
01153     {
01154       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->ssrc_);
01155       index+=4;
01156       ACE_UINT32 temp = ACE_HTONL((local_block_ptr->fraction_&0xff) << 24) &
01157                               local_block_ptr->lost_;
01158       *((ACE_UINT32*)&this->packet_data_[index]) = temp;
01159       index+=4;
01160       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->last_seq_);
01161       index+=4;
01162       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->jitter_);
01163       index+=4;
01164       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->lsr_);
01165       index+=4;
01166       *((ACE_UINT32*)&this->packet_data_[index]) = ACE_HTONL(local_block_ptr->dlsr_);
01167       index+=4;
01168       local_block_ptr = local_block_ptr->next_;
01169     }
01170 }
01171 
01172 void
01173 RTCP_SR_Packet::dump (void)
01174 {
01175   RR_Block *b = this->rr_;
01176   int count = 1;
01177 
01178   ACE_DEBUG ((LM_DEBUG,
01179               "\nRTCP_SR_Packet:: from %u - %d rr blocks follow.\n",
01180               this->ssrc_,
01181               this->chd_.count_));
01182   ACE_DEBUG ((LM_DEBUG,
01183               "    NTP(sec) %u.%u; RTP ts %u\n",
01184               this->ntp_ts_msw_,
01185               this->ntp_ts_lsw_,
01186               this->rtp_ts_));
01187   ACE_DEBUG ((LM_DEBUG,
01188               "    packets sent %u; octets sent %u\n",
01189               this->psent_,
01190               this->osent_));
01191 
01192   while (b)
01193     {
01194       ACE_DEBUG ((LM_DEBUG,
01195                   "  Block %d: ssrc %u; frac %u; lost %u; last seq %u\n",
01196                   count,
01197                   b->ssrc_,
01198                   b->fraction_,
01199                   b->lost_,
01200                   b->last_seq_));
01201       ACE_DEBUG ((LM_DEBUG,
01202                   "           jitter %u; lsr %u; dlsr %u;\n",
01203                   b->jitter_,
01204                   b->lsr_,
01205                   b->dlsr_));
01206 
01207       b = b->next_;
01208       ++count;
01209     }
01210 }
01211 
01212 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:47:49 2010 for TAO_AV by  doxygen 1.4.7