Example #1
0
/**
 *
 * Method Name: ProcessSenderReport
 *
 *
 * Inputs:   unsigned char *puchRTCPReport - A pointer to an RTCP Sender Report
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: Takes the RTCP Sender Report passed and calls the CSenderReport
 *              object's ISenderReport interface to parse the Sender packet and
 *              extract the sender statistics contained therein.  This method
 *              shall also check for the presence of receiver reports within
 *              the packet and call the CReceiverReport object's
 *              IReceiverReport interface to parse and extract its contents.
 *              Although no more than one receiver report is expected under the
 *              current Pingtel call model, it is possible that multiple
 *              receiver reports (one per PingTel source) may be sent.  In this
 *              case,  a new CReceiverReport object shall be created and queued
 *              if not already existing on the Receiver Report list.
 *
 *
 * Usage Notes: Notifications shall be generated to all subscribing parties to
 *              inform them of the receipt of a new Source Report.  The
 *              notification shall contain the event type and a pointer to the
 *              Source Report's IGetSenderStatistics interface.
 *
 *
 */
unsigned long CRTCPSource::ProcessSenderReport(unsigned char *puchRTCPReport)
{

    unsigned long ulSenderSSRC     = GetSenderSSRC(TRUE, puchRTCPReport);
    unsigned long ulReportCount    = 0;
    unsigned long ulBytesProcessed;

    // Has a Sender Report object been instantiated for this participant?
    //  Probably not, if this is the first Sender Report received in a session
    if(m_poSenderReport != NULL);

    // Create The Sender Report Class
    else if((m_poSenderReport =
          new CSenderReport(ulSenderSSRC, m_piSetReceiverStatistics)) == NULL)
    {
        osPrintf("**** FAILURE **** CRTCPSource::ProcessSenderReport() -"
                          " Unable to create Inbound Sender Report Object\n");
        return(GetReportLength(puchRTCPReport));
    }

    // Initialize Sender Report Class
    else if(!m_poSenderReport->Initialize())
    {
        // Release the Sender Report reference.  This should cause the object
        // to be destroyed
        osPrintf("**** FAILURE **** CRTCPSource::ProcessSenderReport() -"
                      " Unable to Initialize Inbound Sender Report Object\n");
        ((ISenderReport *)m_poSenderReport)->Release();
        return(GetReportLength(puchRTCPReport));
    }

    // A Sender object exists to processes this report.  Let's delegate to its
    //  parsing methods to complete this report's processing.
    if((ulBytesProcessed =
                    m_poSenderReport->ParseSenderReport(puchRTCPReport)) == 0)
    {
        osPrintf("**** FAILURE **** CRTCPSource::ProcessSenderReport() -"
                                  " Unable to Parse Inbound Sender Report\n");
        return(GetReportLength(puchRTCPReport));
    }

    // Let's check whether there are Receiver reports associated with this
    //  Sender Report.  If so, delegate to the Receiver Report's processing
    //  method.
    else if((ulReportCount = m_poSenderReport->GetReportCount()) > 0)
    {
        unsigned long ulRRBytesProcessed = 0;

        // Send Event
        SendRTCPEvent(RTCP_SR_RCVD, (void *)m_poSenderReport);

        // Adjust the buffer so that it points to the beginning of the
        //  reception report section.
        puchRTCPReport += ulBytesProcessed;

        // Call Receiver Report processing method.
        if((ulRRBytesProcessed =
                   ProcessReceiverReport(puchRTCPReport, ulReportCount)) == 0)
            return(GetReportLength(puchRTCPReport));

        // Bump Total Byte Processed
        ulBytesProcessed += ulRRBytesProcessed;
    }

    return(ulBytesProcessed);

}
int RTPPacketProcessor::ProcessRTCPBlock(unsigned char *data,int len,unsigned long ip,int port,bool *collis,double localtsunit)
{
	RTCPHeader *rtcphdr;
	unsigned char *data2;
	int type,restlen,calclen;
	int status,count;
	bool firstblock;

	*collis = false;
	if (!initialized)
	{
		delete [] data;
		return ERR_RTP_PACKETPROCESSORNOTINITIALIZED;
	}

	if (ip == conn->GetLocalIP() && port == conn->GetSendPort())
	{
		CheckRTCPHandler(data,len,ip,port); // let user process packet
		
		/* processing own control information is not useful, so we won't
		   do it ... */
		delete [] data;
		return 0;
	}

	curip = ip;
	curport = port;

	data2 = data;
	restlen = len;
	firstblock = true;
	while (restlen >= (int)sizeof(RTCPHeader))
	{
		rtcphdr = (RTCPHeader *)data2;
		data2 += sizeof(RTCPHeader);
		restlen -= sizeof(RTCPHeader);

		if (rtcphdr->version == RTP_VERSION)
		{
			type = rtcphdr->packettype;
			calclen = ntohs(rtcphdr->length);
			calclen *= sizeof(RTPuint32);
			count = rtcphdr->blockcount;
			if (calclen <= restlen) // otherwise not all the info is included
			{
				/* Check if the compound packet starts with a SR or RR */

				if (firstblock)
				{
					firstblock = false;
					if (type != TYPE_RTCP_SR && type != TYPE_RTCP_RR) // not a rtcp compound packet
					{
						CheckRTCPHandler(data,len,ip,port); // let user process packet
						delete [] data;
						return 0;
					}
				}

				/* Just handle the types */

				status = 0;
				switch(type)
				{
				case TYPE_RTCP_SR:
					status = ProcessSenderReport(data2,calclen,count,collis,localtsunit);
					break;
				case TYPE_RTCP_RR:
					status = ProcessReceiverReport(data2,calclen,count,collis,localtsunit);
					break;
				case TYPE_RTCP_SDES:
					if (count > 0)
						status = ProcessSDES(data2,calclen,count,collis,localtsunit);
					break;
				case TYPE_RTCP_BYE:
					if (count > 0)
						status = ProcessBYE(data2,calclen,count);
					break;
				case TYPE_RTCP_APP:
					if (handlers->handlers[RTP_EXCEPTION_RECEIVERTCPAPPDATA].handler != NULL)
						CallAppDataHandler(data2,calclen,count);
					break;
				}
				if (status < 0)
				{
					CheckRTCPHandler(data,len,ip,port); // let user process packet
					delete [] data;
					return status;
				}
			}
		}
		else // Not a rtcp compound packet
		{
			CheckRTCPHandler(data,len,ip,port); // let user process packet
			delete [] data;
			return 0;
		}

		restlen -= calclen;
		data2 += calclen;
	}
	
	if (*collis) // call handler
	{
		if (handlers->handlers[RTP_EXCEPTION_LOCALSSRCCOLLISION].handler != NULL)
			CallLocalSSRCCollHandler(ntohl(contribsrcs->GetLocalSSRC()),ip,false,port);
	}
	CheckRTCPHandler(data,len,ip,port); // let user process packet
	delete [] data;
	return 0;
}
Example #3
0
void CRTCPSource::ProcessPacket(unsigned char *puchDataBuffer,
                                unsigned long ulBufferLength, int verbose)
{

    unsigned char *SAVEpuchDataBuffer = puchDataBuffer;
    unsigned long SAVEulBufferLength = ulBufferLength;

#ifdef DEBUG_RTCP_PACKETS /* [ */
    if (0 < numPacketsToDump--) {
        verbose = 1;
    }

    if (verbose) {
        unsigned char *tp = puchDataBuffer;
        unsigned long tl = ulBufferLength;
        int i = 0;
        osPrintf("CRTCPSource::ProcessPacket(%8p, %lu)\n",
            puchDataBuffer, ulBufferLength);
        while(tl > 0) {
            osPrintf(" %02X", *tp++);
            if (0xf == (0xf & i++)) osPrintf("\n");
            tl--;
        }
        if (0 != (0xf & i)) osPrintf("\n");
    }
#endif /* DEBUG_RTCP_PACKETS ] */

    // This could be either a simple or composite report. Let's process the
    //  buffer until there is nothing more to process.
    while(ulBufferLength > 0)
    {
        unsigned long ulBytesProcessed = 0;

        // Let's peek into the RTCP header to determine the payload type of an
        //  RTCP report and route it to the appropriate handler.
        switch(GetPayloadType(puchDataBuffer))
        {
            // Process Sender Report
            case etSenderReport:
                ulBytesProcessed = ProcessSenderReport(puchDataBuffer);
#ifdef DEBUG_RTCP_PACKETS /* [ */
                if (verbose) {
                    osPrintf("  Sender Report (%lu bytes)\n", ulBytesProcessed);
                }
#endif /* DEBUG_RTCP_PACKETS ] */
                break;

            // Process Receiver Report
            case etReceiverReport:
                ulBytesProcessed = ProcessReceiverReport(puchDataBuffer);
#ifdef DEBUG_RTCP_PACKETS /* [ */
                if (verbose) {
                    osPrintf("  Recvr Report (%lu bytes)\n", ulBytesProcessed);
                }
#endif /* DEBUG_RTCP_PACKETS ] */
                break;

            // Process Source Description Report
            case etSDESReport:
                ulBytesProcessed = ProcessSDESReport(puchDataBuffer);
#ifdef DEBUG_RTCP_PACKETS /* [ */
                if (verbose) {
                    osPrintf("  SDES Report (%lu bytes)\n", ulBytesProcessed);
                }
#endif /* DEBUG_RTCP_PACKETS ] */
                break;

            // Process Bye Report
            case etByeReport:
                ulBytesProcessed = ProcessByeReport(puchDataBuffer);
#ifdef DEBUG_RTCP_PACKETS /* [ */
                if (verbose) {
                    osPrintf("  Bye Report (%lu bytes)\n", ulBytesProcessed);
                }
#endif /* DEBUG_RTCP_PACKETS ] */
                break;

            // Process Application Report
            case etAppReport:
                ulBytesProcessed = ProcessAppReport(puchDataBuffer);
#ifdef DEBUG_RTCP_PACKETS /* [ */
                if (verbose) {
                    osPrintf("  App Report (%lu bytes)\n", ulBytesProcessed);
                }
#endif /* DEBUG_RTCP_PACKETS ] */
                break;

            // Unrecognized Report
            default:
                {
                   int count, i;

                   osPrintf("** TROUBLE ** CRTCPSource::ProcessPacket()"
                       " - Unrecognized RTCP Report Type of %d\n",
                       GetPayloadType(puchDataBuffer));
                   osPrintf(" - Remaining buffer length of %lu",
                       ulBufferLength);
                   count = ulBufferLength > 0 ? ulBufferLength : 0;
                   count = count < 100 ? count : 100;
                   if (count > 0) osPrintf(" containing\n==>");
                   for (i=0; i<count; i++) {
                       if (15 == (15 & i))
                          osPrintf(" %02X\n   ", *puchDataBuffer);
                       else
                          osPrintf(" %02X", *puchDataBuffer);
                       puchDataBuffer++;
                   }
                   osPrintf("\n");
                }
                if (!verbose) {
                    ProcessPacket(SAVEpuchDataBuffer, SAVEulBufferLength, 1);
                }
                return;
        }

#ifdef DEBUG_RTCP_PACKETS /* [ */
        if (verbose) {
            unsigned char *tp = puchDataBuffer;
            unsigned long tl = ulBytesProcessed;
            int i = 0;
            while(tl > 0) {
                osPrintf(" %02X", *tp++);
                if (0xf == (0xf & i++)) osPrintf("\n");
                tl--;
            }
            if (0 != (0xf & i)) osPrintf("\n");
        }
#endif /* DEBUG_RTCP_PACKETS ] */
        // Adjust length remaining and the buffer pointer so that we are
        // prepared to recognize and process other reports.
        puchDataBuffer  += ulBytesProcessed;
        ulBufferLength -= ulBytesProcessed;

    }
}