/** * * 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; }
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; } }