Beispiel #1
0
/**
 *
 * Method Name:  ParseByeReport
 *
 *
 * Inputs:   unsigned char *puchReportBuffer - Buffer containing the Bye Report
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: Extracts the contents of an Bye report using the buffer
 *              passed in by the caller.
 *
 * Usage Notes: The header of the RTCP Report shall be parsed by delegating
 *              to the base class.
 *
 *
 */
unsigned long CByeReport::ParseByeReport(unsigned char *puchReportBuffer)
{

    unsigned char    *puchPayloadBuffer = puchReportBuffer;

    // Check whether the RTCP Header has been correctly
    //   formed (Version, etc...).
    if(!ParseRTCPHeader(puchReportBuffer))
        return(GetReportLength());

    // Good header.  Let's bump the payload pointer and continue.
    puchPayloadBuffer += GetHeaderLength();


    // Let's store the CSRCs from the Bye Report
    unsigned long ulCSRCCount = GetReportCount() ? GetReportCount() - 1 : 0;

    SetCSRC((ssrc_t *)puchPayloadBuffer, ulCSRCCount, TRUE);
    puchPayloadBuffer += (sizeof(ssrc_t) * ulCSRCCount);

    // Let's determine whether there is an optional Reason field associated
    // with this Bye Report.  We can surmise this through comparing the
    // packet length to what we've already processed

    if(puchPayloadBuffer - puchReportBuffer < (long)GetReportLength())
    {
        uint32_t ulReasonLength = (uint32_t)*puchPayloadBuffer++;
        SetReason(puchPayloadBuffer, ulReasonLength);
        puchPayloadBuffer += ulReasonLength;

    }

    // Let's process any padding that might be present to align the
    // payload on a 32 bit boundary.
    if(GetPadding())
        puchPayloadBuffer += ExtractPadding(puchPayloadBuffer);

    return(puchPayloadBuffer - puchReportBuffer);

}
Beispiel #2
0
/**
 *
 * Method Name:  ParseSenderReport
 *
 *
 * Inputs:   unsigned char *puchReportBuffer
 *                               - Buffer containing the Sender Report
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: Extracts the contents of an Sender report using the buffer
 *              passed in by the caller.  The Sender Report object shall store
 *              the content and length of data fields extracted from the Sender
 *              Report.  The timestamps identifying the time of SR report
 *              reception shall obtained and sent with the SR Send timestamp to
 *              the associated Receiver Report through the SetLastRcvdSRTime()
 *              method of the ISetReceiverStatistics interface.
 *
 * Usage Notes: The header of the RTCP Report shall be parsed by delegating to
 *              the base class.
 *
 *
 */
unsigned long CSenderReport::ParseSenderReport(unsigned char *puchReportBuffer)
{

    unsigned char   *puchPayloadBuffer = puchReportBuffer;

    // Check whether the RTCP Header has been correctly
    //  formed (Version, etc...).
    if(!ParseRTCPHeader(puchReportBuffer))
        return(GetReportLength());

    // Good header.  Let's bump the payload pointer and continue.
    puchPayloadBuffer += GetHeaderLength();

    // Let's extract the NTP and RTP timestamps from the Sender Report
    puchPayloadBuffer += ExtractTimestamps((unsigned long *)puchPayloadBuffer);

    // Let's extract the Sender Statistics
    puchPayloadBuffer += ExtractSenderStats((unsigned long*)puchPayloadBuffer);

    return(puchPayloadBuffer - puchReportBuffer);

}
Beispiel #3
0
/**
 *
 * Method Name: ProcessByeReport
 *
 *
 * Inputs:   unsigned char *puchRTCPReport - A pointer to an RTCP Bye Report
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: Takes the RTCP Bye Report and extracts the associated SSRC ID.
 *              A notification shall be generated to all subscribing parties to
 *              inform them of the receipt of the BYE along with the associated
 *              SSRC ID.
 *
 *
 * Usage Notes:
 *
 *
 */
unsigned long CRTCPSource::ProcessByeReport(unsigned char *puchRTCPReport)
{
    unsigned long ulSenderSSRC     = GetSenderSSRC(TRUE, puchRTCPReport);
    unsigned long ulBytesProcessed = GetReportLength(puchRTCPReport);

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

    // Create The Bye Report Class
    else if((m_poByeReport = new CByeReport(ulSenderSSRC)) == NULL)
    {
        osPrintf("**** FAILURE **** CRTCPSource::ProcessByeReport()"
                           " - Unable to Create Inbound Bye Report Object\n");
        return(ulBytesProcessed);
    }

    // Initialize Bye Report Class
    else if(!m_poByeReport->Initialize())
    {
        // Release the Bye Report reference.  This should cause the object
        // to be destroyed
        osPrintf("**** FAILURE **** CRTCPSource::ProcessByeReport()"
                       " - Unable to Initialize Inbound Bye Report Object\n");
        ((IByeReport *)m_poByeReport)->Release();
        return(ulBytesProcessed);
    }

    // A Bye object exists to processes this report.  Let's delegate to its
    // parsing methods to complete this report's processing.
    m_poByeReport->ParseByeReport(puchRTCPReport);

    // Set the event mask to refelect receiving this report
    SendRTCPEvent(RTCP_BYE_RCVD, (void *)m_poByeReport);

    return(ulBytesProcessed);

}
Beispiel #4
0
/**
 *
 * Method Name: ProcessAppReport
 *
 *
 * Inputs:   unsigned char *puchRTCPReport
 *                                   - A pointer to an RTCP Application Report
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: No processing is performed on an Application Report but the
 *              length is extracted from the header and returned so that other
 *              composite reports might still be processed.
 *
 *
 * Usage Notes:
 *
 *
 */
unsigned long CRTCPSource::ProcessAppReport(unsigned char *puchRTCPReport)
{

    // Disregard this packet
    return(GetReportLength(puchRTCPReport));
}
Beispiel #5
0
/**
 *
 * Method Name: ProcessSDESReport
 *
 *
 * Inputs:   unsigned char *puchRTCPReport
 *                              - pointer to an RTCP Source Description Report
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: Takes the RTCP SDES Report passed and calls the
 *              CSourceDescription object's ISDESReport interface to parse the
 *              Source Description packet and extract the identification
 *              information contained therein.
 *
 *
 * Usage Notes: A call connection to a Mixer would cause all SDES Reports to
 *              be forward as multiple SDES Reports. In this case, a new
 *              CSourceDescription object shall be created and queued if not
 *              already existing on the SrcDescription list.  The SSRC ID will
 *              be used to determine uniqueness among reports.
 *
 *              Notifications shall be generated to all subscribing parties to
 *              inform them of the new Source Descriptions or changes in
 *              previously existing Source Descriptions.  The notification
 *              shall contain the event type and a pointer to the new or
 *              modified Source Description interface (IGetSrcDescription).
 */
unsigned long CRTCPSource::ProcessSDESReport(unsigned char *puchRTCPReport)
{

    bool                bRTCPHeader      = TRUE;
    unsigned long       ulEventMask      = 0;
    unsigned long       ulSDESLength     = 0;
    unsigned long       ulReportCount    = 0;
    unsigned long       ulSenderSSRC     = 0;
    unsigned long       ulReportSize     = GetReportLength(puchRTCPReport);
    CSourceDescription *poSDESReport     = NULL;

    // Pull the Report Count from the header so we no how many reports we need
    //  to process
    ulReportCount = GetReportCount(puchRTCPReport);

    // Let's prepare to iterate through each reception report until complete
    while(ulReportCount > 0)
    {
        // Extract the corresponding SSRC with the knowledge that this report
        //  comes with a full formed RTCP header.
        ulSenderSSRC = GetSenderSSRC(bRTCPHeader, puchRTCPReport);

        // Has a SDES Report object been instantiated for this participant?
        // Probably not, if this is the first SDES Report received in a session
        if((poSDESReport = m_tSrcDescriptorList.GetEntry(SDESSsrcComparitor,
                                              (void *)ulSenderSSRC)) != NULL);

        // Create The SDES Report object
        else if((poSDESReport = new CSourceDescription(ulSenderSSRC)) == NULL)
        {
            osPrintf("**** FAILURE **** CRTCPSource::ProcessSDESReport()"
                          " - Unable to Create Inbound SDES Report Object\n");
            return(ulReportSize);
        }

        // Initialize SDES Report object
        else if(!poSDESReport->Initialize())
        {
            // Release the SDES Report reference.  This should cause the
            //  object to be destroyed
            osPrintf("**** FAILURE **** CRTCPSource::ProcessSDESReport()"
                      " - Unable to Initialize Inbound SDES Report Object\n");
            ((ISDESReport *)poSDESReport)->Release();
            return(ulReportSize);
        }

        // Place the new SDES Report object on the collection list
        else if(!m_tSrcDescriptorList.AddEntry(poSDESReport))
        {
            // Release the SDES Report reference.
            // This should cause the object to be destroyed
            osPrintf("**** FAILURE **** CRTCPSource::ProcessSDESReport()"
                       " - Unable to Add SDES Report Object to Collection\n");
            ((ISDESReport *)poSDESReport)->Release();
            return(ulReportSize);
        }

        else
        {
            // Set the event mask to indicate that a new SDES was received
            ulEventMask |= RTCP_NEW_SDES;
        }


        // A SDES object exists to processes this report.  Let's delegate to
        //  its parsing methods to complete this report's processing.
        if((ulSDESLength =
             poSDESReport->ParseSDESReport(bRTCPHeader, puchRTCPReport)) == 0)
        {
            osPrintf("**** FAILURE **** CRTCPSource::ProcessSDESReport()"
                                  " - Unable to Parse Inbound SDES Report\n");
            return(ulReportSize);
        }

        // We've made it through our first SDES report successfully and we must
        // adjust the flags, counts, and report pointers for the next go-round.
        bRTCPHeader     = FALSE;
        puchRTCPReport  += ulSDESLength;
        ulReportCount--;

        // Check whether any information has changed in an existing SDES Report
        ulEventMask |= RTCP_SDES_UPDATE;
        SendRTCPEvent(ulEventMask,
                            (void *)poSDESReport, poSDESReport->GetChanges());
        ulEventMask = 0;

    }

    return(ulReportSize);
}
Beispiel #6
0
/**
 *
 * Method Name: ProcessReceiverReport
 *
 *
 * Inputs:   unsigned char *puchRTCPReport - pointer to an RTCP Receiver Report
 *           unsigned long ulReportCount   - Optional Count of receiver reports
 *
 * Outputs:  None
 *
 * Returns:  unsigned long
 *
 * Description: Takes the RTCP Receiver Report passed and calls the
 *              CReceiverReport object's IReceiverReport interface to parse the
 *              Receiver packet and extract the receiver statistics contained
 *              therein.  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 Receiver Report.  The
 *              notification shall contain the event type and a pointer to the
 *              Receiver Report's IGetReceiverStatistics interface.
 *
 *
 */
unsigned long CRTCPSource::ProcessReceiverReport(unsigned char *puchRTCPReport,
                                                 unsigned long ulReportCount)
{
    bool             bRTCPHeader      = FALSE;
    unsigned long    ulReceiverSSRC   = 0;
    CReceiverReport *poReceiverReport = NULL;
    unsigned long    ulBytesProcessed = 0;
    unsigned long    ulReportSize     = 0;

    // Determine the Receiver Report count if it hasn't already been provided
    //  to us.
    if(ulReportCount == 0)
    {
        // Set a flag to identify the existence of an RTCP Header
        bRTCPHeader = TRUE;

        // Pull the Report Count from the header so we know how many reports
        //  we need to process
        ulReportCount = GetReportCount(puchRTCPReport);
        if (0 == ulReportCount) {
            // $$$ bRTCPHeader is the culprit that makes this necessary...
            //   It is passed to a couple of routines that should not care
            //   whether the header is still present.  The header is
            //   processed in the call to ParseReceiverReport when the
            //   header flag is set.  That processing should be done here,
            //   the length set to 8, then all the remaining reports should
            //   be processed without regard to the header.  But
            //         BETTER IS THE ENEMY OF GOOD!
            //   hzm 16Aug01
            ulReportSize = GetReportLength(puchRTCPReport);
            osPrintf("ProcessReceiverReport: RR/RC=0, len=%lu\n", ulReportSize);
        }
    }

    // Let's prepare to iterate through each reception report until complete
    while(ulReportCount > 0)
    {

        // Extract the corresponding SSRC with the knowledge that this report
        //  comes with a full formed RTCP header.
        ulReceiverSSRC = GetReceiverSSRC(bRTCPHeader, puchRTCPReport);

        // Has a Receiver Report object been instantiated for this participant?
        // Probably not, if this is the first Receiver Report received in a
        //  session
        if((poReceiverReport = m_tReceiverReportList.GetEntry(RRSsrcComparitor,
                                             (void *)ulReceiverSSRC)) != NULL);

  // $$$ IS THE ABOVE LINE, ENDING WITH A SEMICOLON, CORRECT??? - hzm

        // Create The Receiver Report object
        else if((poReceiverReport =
                                 new CReceiverReport(ulReceiverSSRC)) == NULL)
        {
            osPrintf("**** FAILURE **** CRTCPSource::ProcessReceiverReport()"
                      " - Unable to create Inbound Receiver Report Object\n");
            return(ulReportSize);
        }

        // Initialize Receiver Report object
        else if(!poReceiverReport->Initialize())
        {
            // Release the Receiver Report reference.
            // This should cause the object to be destroyed
            osPrintf("**** FAILURE **** CRTCPSource::ProcessReceiverReport()"
                  " - Unable to Initialize Inbound Receiver Report Object\n");
            ((IReceiverReport *)poReceiverReport)->Release();
            return(ulReportSize);
        }

        // Place the new Receiver Report object on the collection list
        else if(!m_tReceiverReportList.AddEntry(poReceiverReport))
        {
            // Release the Receiver Report reference.
            // This should cause the object to be destroyed
            osPrintf("**** FAILURE **** CRTCPSource::ProcessReceiverReport()"
           " - Unable to Add Inbound Receiver Report Object to Collection\n");
            ((IReceiverReport *)poReceiverReport)->Release();
            return(ulReportSize);
        }

        // A Receiver object exists to process this report.
        // Let's delegate to its parsing methods to complete this report's
        //  processing.
        if((ulBytesProcessed =
           poReceiverReport->ParseReceiverReport(bRTCPHeader, puchRTCPReport))
           == 0)
        {
            osPrintf("**** FAILURE **** CRTCPSource::ProcessReceiverReport()"
                              " - Unable to Parse Inbound Receiver Report\n");
            return(ulReportSize);
        }

        // We've made it through our first receiver report successfully and we
        //  must adjust the flags, counts, and report pointers for the next
        //  go-round.
        bRTCPHeader     = FALSE;
        ulReportSize    += ulBytesProcessed;
        puchRTCPReport  += ulBytesProcessed;
        ulReportCount--;

        // Send Event
        SendRTCPEvent(RTCP_RR_RCVD, (void *)poReceiverReport);

    }

    return(ulReportSize);
}
Beispiel #7
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);

}