Public Member Functions | Private Member Functions | Private Attributes

RTCP_SDES_Packet Class Reference

The Source Description packet is sent by all members of a session. At a minimum, the canonical name (or CNAME) is sent with each RTCP packet. Other items such as name, email, or location are included less frequently. More...

#include <RTCP_Packet.h>

Inheritance diagram for RTCP_SDES_Packet:
Inheritance graph
[legend]
Collaboration diagram for RTCP_SDES_Packet:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 RTCP_SDES_Packet (char *buffer, int *len)
 Constructor for incoming SDES packets.
 RTCP_SDES_Packet (void)
 Constructor for outgoing SDES packets.
virtual ~RTCP_SDES_Packet (void)
 Destructor.
void add_item (ACE_UINT32 ssrc, unsigned char type, unsigned char length, const char *data)
void add_priv_item (ACE_UINT32 ssrc, unsigned char nameLength, const char *name, unsigned char dataLength, const char *data)
unsigned int packet_size (void)
 Returns the size of the packet in bytes.
void dump (void)
 Prints the contents of the packet.
ACE_UINT32 ssrc (void)

Private Member Functions

void build_packet (void)
 Used to create the byte representation of the RTCP packet.
void add_chunk (ACE_UINT32 ssrc)
 Add a chunk to the packet.

Private Attributes

unsigned long num_chunks_
sdesChunk_tchunk_
 A linked list of chunks for this packet (only 1 for non-mixers).

Detailed Description

The Source Description packet is sent by all members of a session. At a minimum, the canonical name (or CNAME) is sent with each RTCP packet. Other items such as name, email, or location are included less frequently.

Definition at line 276 of file RTCP_Packet.h.


Constructor & Destructor Documentation

RTCP_SDES_Packet::RTCP_SDES_Packet ( char *  buffer,
int *  len 
)

Constructor for incoming SDES packets.

Definition at line 464 of file RTCP_Packet.cpp.

                                                        :
                   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_ = ACE_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]);
              ACE_OS::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]);
              ACE_OS::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]);
              ACE_OS::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   ) 

Constructor for outgoing SDES packets.

Definition at line 452 of file RTCP_Packet.cpp.

                                       :
                   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 ( void   )  [virtual]

Destructor.

Definition at line 565 of file RTCP_Packet.cpp.

{
  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_;
}


Member Function Documentation

void RTCP_SDES_Packet::add_chunk ( ACE_UINT32  ssrc  )  [private]

Add a chunk to the packet.

Definition at line 604 of file RTCP_Packet.cpp.

{
  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 
)

This will add a standard item of type and length for the ssrc specified. When the first item for a ssrc is added, a chunk is created. Subsequent items for that ssrc are added to the same chunk. New chunks are created for each unique ssrc.

Definition at line 636 of file RTCP_Packet.cpp.

{
  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]);

  ACE_OS::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 
)

This will add a private item using the name and data for the ssrc specified. When the first item for a ssrc is added, a chunk is created. Subsequent items for that ssrc are added to the same chunk. New chunks are created for each unique ssrc.

Definition at line 705 of file RTCP_Packet.cpp.

{
  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]);

  ACE_OS::memcpy(ip->info_.priv_.name_, name, nameLength);
  ACE_OS::memcpy(ip->info_.priv_.data_, data, dataLength);
}

void RTCP_SDES_Packet::build_packet ( void   )  [private, virtual]

Used to create the byte representation of the RTCP packet.

Implements RTCP_Packet.

Definition at line 819 of file RTCP_Packet.cpp.

{
  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]) = ACE_HTONS(chd_.length_);
  index+=2;

  cp = this->chunk_;
  while (cp)
    {
      *((ACE_UINT32*)&this->packet_data_[index]) = ACE_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   ) 

Prints the contents of the packet.

Definition at line 902 of file RTCP_Packet.cpp.

{
  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_;
    }

}

unsigned int RTCP_SDES_Packet::packet_size ( void   )  [virtual]

Returns the size of the packet in bytes.

Implements RTCP_Packet.

Definition at line 780 of file RTCP_Packet.cpp.

{
  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;
}

ACE_UINT32 RTCP_SDES_Packet::ssrc ( void   )  [inline]

This returns the synchronization source id for this packet. This assumes that this source is only receiving messages from end systems (i.e. only one source id per SDES)

Definition at line 316 of file RTCP_Packet.h.

{ return this->chunk_->ssrc_; }


Member Data Documentation

A linked list of chunks for this packet (only 1 for non-mixers).

Definition at line 332 of file RTCP_Packet.h.

unsigned long RTCP_SDES_Packet::num_chunks_ [private]

The number of chunks contained in this packet. 1 for end systems, 1+ for mixers

Definition at line 327 of file RTCP_Packet.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines