// RTPPacket.cpp: implementation of the RTPPacket class.
|
//
|
//////////////////////////////////////////////////////////////////////
|
|
#include "RTPPacket.h"
|
#include "Exception.h"
|
#include "TraceUser.h"
|
|
RTPPacket *
|
RTPPacket::CreateRTPPacket(char *buffer, int len, Tracer *tracer)
|
{
|
int returnCode = 0;
|
RTPPacket *rtpPacket = NULL;
|
|
// make a copy of the class variables so that we can fill them in to test
|
// for the validity of the packet before we create the RTPPacket structure
|
bool headerExtension;
|
unsigned char contributorCount;
|
bool marker;
|
unsigned char payloadType;
|
unsigned short seqNo;
|
unsigned long timestamp;
|
unsigned long ssrc;
|
unsigned long dataLen;
|
char *rtpData;
|
unsigned char version;
|
unsigned long headerLength;
|
|
char *packetPtr;
|
unsigned long totalLength;
|
unsigned long numPadding;
|
|
try
|
{
|
if (len < 12)
|
{
|
throw Exception(-10, "invalid RTP packet : len = %d bytes", len);
|
}
|
packetPtr = buffer;
|
totalLength = len;
|
numPadding = packetPtr[0] & 0x20 ? packetPtr[totalLength - 1] : 0;
|
|
headerExtension = (packetPtr[0] & 0x10) != 0;
|
if (headerExtension)
|
{
|
throw Exception(-20, "header extension not supported");
|
}
|
|
contributorCount = packetPtr[0] & 0x0f;
|
marker = (packetPtr[1] & 0x80) != 0;
|
payloadType = packetPtr[1] & 0x7f;
|
seqNo = ntohs(*((short *)(packetPtr + 2)));
|
timestamp = ntohl(*((unsigned long *)(packetPtr + 4)));
|
ssrc = ntohl(*((unsigned long *)(packetPtr + 8)));
|
|
version = (packetPtr[0] & 0xc0) >> 6;
|
if (version != 2)
|
{
|
throw Exception(-30, "invalid RTP version %d", version);
|
}
|
|
headerLength = 12 + 4 * contributorCount;
|
if (totalLength < headerLength)
|
{
|
throw Exception(-40, "totalLength (%d) < headerLength (%d) ! contributor count = %d", totalLength, headerLength, contributorCount);
|
}
|
|
if (totalLength < (headerLength + numPadding))
|
{
|
throw Exception(-50, "totalLength (%d) < headerLength (%d) + numPadding (%d)", totalLength, headerLength, numPadding);
|
}
|
dataLen = totalLength - headerLength - numPadding;
|
rtpData = packetPtr + headerLength;
|
|
// now that all checks have been made, we will create and return the RTP packet
|
rtpPacket = new RTPPacket(buffer, len);
|
}
|
catch (Exception exception)
|
{
|
tracer->tracef(ERR, "RTPPacket::CreateRTPPacket : error %d : %s\n", exception.ErrorCode(), exception.ErrorMessage());
|
if (rtpPacket)
|
{
|
delete rtpPacket;
|
}
|
rtpPacket = NULL;
|
}
|
return rtpPacket;
|
}
|
|
RTPPacket *
|
RTPPacket::CloneHeader()
|
{
|
RTPPacket *newHeader = new RTPPacket(this->packetPtr, this->headerLength);
|
if (newHeader)
|
{
|
newHeader->packetPtr = NULL;
|
newHeader->rtpData = NULL;
|
}
|
return newHeader;
|
}
|