How TO USE THE RTCP PARSER LIBRARY
**********************************

Introduction:
_____________

THe RTCP parser APIs help parse the contents of a compound RTCP Packet, into 
individual packets. The individual packet types can be further parsed for the 
actual content.


The parser APIs are basically of three types

1. Convenience APIs
These APIs like GetBits8(), rtcp_NetToHost16() etc are used internally by the
parser APIs for conversion from Host to Network order or for extracting certain
portions of the packet content while parsing. Generally users do not need to use 
these APIs directly.

2. General APIs
These APIs are used to first check the validity and correctness of the compound
RTCP packet. Some of these APIs work on the entire compound RTCP packet and others
work on individual RTCP packet.

3. Individual Report APIs
Based on the type of the RTCP packet or report, these APIs work accordingly.

4. Return codes
There are two enumerations defined for this purpose
typedef enum
{
	RTCP_SUCCESS = 	1,
	RTCP_FAILURE = 	-1
}eRTCP_Ret_Code;
All API return one of these enumerations to indicate the success or failure of
the function call. They do not gurantee if the functionality within the API 
worked or not.

5. Memory Allocation
None of the parser APIs allocate memory internally. All the memory allocation 
required for parsing should be allocated by the application itself. Most of the
APIs check for the validity of the memory that has been passed to them.


Parsing Methodology
___________________

The following steps show how to use these APIS.
1. The compound RTCP packet which needs to be parsed has to be validated first
by using rtcp_ValidatePkt() API as shown below:

unsigned char* 	data; 		// Unparsed RTCP data
UInt16		len;  		// Length of the Unparsed RTCP data
UInt8		result; 	// Data holder for the result

if( RTCP_SUCCESS == rtcp_ValidatePkt(data, len, &result))
{
   if(RTCP_PKT_VALID == result)
   {
	// Perform error processing	
   }
}


2. The number of individual packets in the compound RTCP packet should be determined
using rtcp_GetNumPkts() API as shown below:

unsigned char* 	data; 		// Unparsed RTCP data
UInt16		len;  		// Length of the Unparsed RTCP data
UInt8		numpkts; 	// Data holder for number of packets

if( RTCP_SUCCESS != rtcp_GetNumPkts(data, len, &numpkts))
{
	// Perform error processing
}

The number of packets returned through this API is needed for further parsing.

3. Retrieve the pointer to individual packets and store in the array using
the rtcp_GetPktsPtr() API as below.

// Allocate Memory based on number of packets in the compound RTCP Packet 
// for example:

RTCP_Pkt_Header** hdrarr = NULL; // Two Dim Array for storing indiv. RTCP packets
hdrarr = malloc(numpkts * sizeof(RTCP_Pkt_Header *));

// Use this array and parse out the start of individual packet headers as follows
unsigned char* 	data; 		// Unparsed RTCP data
UInt16		len;  		// Length of the Unparsed RTCP data
UInt8		numpkts; 	// Data holder for number of packets

if(RTCP_SUCCESS != rtcp_GetPktsPtr(data, len, hdrarr, numpkts))
{
	// Perform error processing

}

4. Using the individual packet headers, call appropriate Report APIs. For example to
parse data related to Sender Report, use the following steps:

a. Construct the memory for the Sender report by looking for the presence of
its components and their length if present. 

b. Once the memory is allocated properly, it can be passed to the rtcp_GetSRRpt() along 
with the unparsed data. The API if successful will return the parsed data in the 
structure provided.

RTCP_Pkt_Header*   temp = NULL;  // Temporary holder for packet header
UInt16		   pkttype = 0;  // Data holder for Packet Type
RTCP_Sender_Report sr;      	 // Memory for storing the parsed Sender Report
SRRR_ReportBlock** srrr = NULL;	 // Data holder for Sender Report Repor Blocks
UInt16		   proflen = 0;  // Data holder for Prof Extension Length


temp = (RTCP_Pkt_Header *)(hdrarr[0]); // Assuming we stored it as first element
pkttype = temp->PacketType;

if(pkttype == RTCP_PKTTYPE_SR)
{

   // Initialize the memory
   memset(&sr, 0, sizeof(RTCP_Sender_Report));

   // Allocate memory for the header portion
   sr.SR_Header = malloc(sizeof(RTCP_Pkt_Header));

   // Now Parse the individual Report components
   // Get the number Report Blocks present in the Sender Report
   if(RTCP_SUCCESS != rtcp_GetNumRptBlks(temp, &numblks))
   {
	sr.rptblk = NULL;
	// Perform Error processing
   }
   else
   {
      // Allocate memory for all the report blocks
      srrr = malloc( numblks * sizeof(SRRR_ReportBlock *));
      for(j=0; j < numblks; j ++)
      {
	srrr[j] = malloc(sizeof(SRRR_ReportBlock));
      }
	
      sr.rptblk = srrr;
   }
  
   // Check if there is a Profile Extension Present
   if(RTCP_SUCCESS == rtcp_GetProfExtLen(temp, &proflen))
   {
      if(0 < proflen)
      {
	sr.ProfileExt = malloc(proflen * sizeof(UInt8));
      }
      else
	sr.ProfileExt = NULL;
   }

   // Finally send it to the Report parser API   
   if(RTCP_SUCCESS == rtcp_GetSRRpt(temp, &sr)) 
   {
	 // Perform data processing
   }
}