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