blob: 06f0cef2ab6ea91234f1894aab78beeac2381353 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#include "oscl_snprintf.h"
#include "rtsp_par_com.h"
#include "rtsp_range_utils.h"
#include "oscl_time.h"
OSCL_EXPORT_REF void
RTSPOutgoingMessage::reset()
{
RTSPGenericMessage::reset();
fullRequestBufferSizeUsed = 0;
fullRequestBufferSpace = fullRequestBuffer;
boundMessage = NULL;
}
OSCL_EXPORT_REF StrPtrLen *
RTSPOutgoingMessage::retrieveComposedBuffer()
{
return &fullRequestPLS;
}
OSCL_EXPORT_REF bool
RTSPOutgoingMessage::addField(
StrCSumPtrLen * newFieldName,
const StrPtrLen * newFieldValue
)
{
StrPtrLen * fieldVal = const_cast<StrPtrLen *>(queryField(* newFieldName));
uint32 extraSize;
// check if this field already exists in the message
//
if (NULL == fieldVal)
{ // this field is new to the message
// check that there are enough pointers
if (RTSP_MAX_NUMBER_OF_FIELDS == numPtrFields)
{
return false;
}
// check for the extra size
extraSize = newFieldName->length() + newFieldValue->length() + 2;
if (RTSP_MAX_FULL_REQUEST_SIZE < secondaryBufferSizeUsed + extraSize)
{
return false;
}
// oscl_memcpy is unsafe for overlaps, but source and target memory come from
// different sources
//
oscl_memcpy(secondaryBufferSpace, newFieldName->c_str(),
newFieldName->length() + 1);
oscl_memcpy(secondaryBufferSpace + newFieldName->length() + 1,
newFieldValue->c_str(), newFieldValue->length() + 1);
// save the incoming structures, but reset pointers to their new home in the
// secondary buffer
fieldKeys[ numPtrFields ].setPtrLen(secondaryBufferSpace,
newFieldName->length());
fieldVals[ numPtrFields ].setPtrLen(
secondaryBufferSpace + newFieldName->length() + 1,
newFieldValue->length()
);
// pop up the number of used pointers
//
++ numPtrFields;
// do buffer accounting
//
}
else
{ // this field is known to the message, we just have to replace its value
// check for the extra size
extraSize = newFieldValue->length() + 1;
if (RTSP_MAX_FULL_REQUEST_SIZE < secondaryBufferSizeUsed + extraSize)
{
return false;
}
// oscl_memcpy is unsafe for overlaps, but source and target memory come from
// different sources
//
oscl_memcpy(secondaryBufferSpace, newFieldValue->c_str(),
newFieldValue->length() + 1);
// save the incoming structures, but reset pointers to their new home in the
// secondary buffer
fieldVal->setPtrLen(secondaryBufferSpace, newFieldValue->length());
}
secondaryBufferSizeUsed += extraSize;
secondaryBufferSpace = secondaryBuffer + secondaryBufferSizeUsed;
return true;
}
OSCL_EXPORT_REF bool
RTSPOutgoingMessage::addField(
StrCSumPtrLen * newFieldName,
const char * newValue
)
{
StrPtrLen valuePLS(newValue);
return addField(newFieldName, &valuePLS);
}
OSCL_EXPORT_REF bool
RTSPOutgoingMessage::compose()
{
// compose the first line
//
switch (msgType)
{
case RTSPResponseMsg:
{
// RTSP version
//
oscl_memcpy(fullRequestBuffer, RTSPVersionString, RTSPVersionString_len);
fullRequestBufferSpace += RTSPVersionString_len;
*(fullRequestBufferSpace++) = ' ';
// Status code
//
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%d", statusCode);
// resync the pointer and size used
fullRequestBufferSizeUsed = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSpace += fullRequestBufferSizeUsed;
*(fullRequestBufferSpace++) = ' ';
fullRequestBufferSizeUsed += 1 + RTSPVersionString_len + 1;
if (0 != reasonString.length())
{
// user specified his own string
//
oscl_memcpy(fullRequestBufferSpace, reasonString.c_str(),
reasonString.length());
fullRequestBufferSpace += reasonString.length();
fullRequestBufferSizeUsed += reasonString.length();
}
else
{
StrPtrLen realReasonString ;
// user wants the built-in default
//
switch (statusCode)
{
case CodeContinue:
realReasonString = RtspReasonStringContinue;
break;
case CodeOK:
realReasonString = RtspReasonStringOK;
break;
case CodeCreated:
realReasonString = RtspReasonStringCreated;
break;
case CodeLowOnStorageSpace:
realReasonString = RtspReasonStringLowOnStorageSpace;
break;
case CodeMultipleChoices:
realReasonString = RtspReasonStringMultipleChoices;
break;
case CodeMovedPermanently:
realReasonString = RtspReasonStringMovedPermanently;
break;
case CodeMovedTemporarily:
realReasonString = RtspReasonStringMovedTemporarily;
break;
case CodeSeeOther:
realReasonString = RtspReasonStringSeeOther;
break;
case CodeNotModified:
realReasonString = RtspReasonStringNotModified;
break;
case CodeUseProxy:
realReasonString = RtspReasonStringUseProxy;
break;
case CodeBadRequest:
realReasonString = RtspReasonStringBadRequest;
break;
case CodeUnauthorized:
realReasonString = RtspReasonStringUnauthorized;
break;
case CodePaymentRequired:
realReasonString = RtspReasonStringPaymentRequired;
break;
case CodeForbidden:
realReasonString = RtspReasonStringForbidden;
break;
case CodeNotFound:
realReasonString = RtspReasonStringNotFound;
break;
case CodeMethodNotAllowed:
realReasonString = RtspReasonStringMethodNotAllowed;
break;
case CodeNotAcceptable:
realReasonString = RtspReasonStringNotAcceptable;
break;
case CodeProxyAuthenticationRequired:
realReasonString =
RtspReasonStringProxyAuthenticationRequired;
break;
case CodeRequestTimeOut:
realReasonString = RtspReasonStringRequestTimeOut;
break;
case CodeGone:
realReasonString = RtspReasonStringGone;
break;
case CodeLengthRequired:
realReasonString = RtspReasonStringLengthRequired;
break;
case CodePreconditionFailed:
realReasonString = RtspReasonStringPreconditionFailed;
break;
case CodeRequestEntityTooLarge:
realReasonString =
RtspReasonStringRequestEntityTooLarge;
break;
case CodeRequestURITooLarge:
realReasonString = RtspReasonStringRequestURITooLarge;
break;
case CodeUnsupportedMediaType:
realReasonString = RtspReasonStringUnsupportedMediaType;
break;
case CodeSessionNotFound:
realReasonString = RtspReasonStringSessionNotFound;
break;
case CodeMethodNotValidInThisState:
realReasonString = RtspReasonStringMethodNotValidInThisState;
break;
case CodeHeaderFieldNotValidForResource:
realReasonString =
RtspReasonStringHeaderFieldNotValidForResource;
break;
case CodeInvalidRange:
realReasonString = RtspReasonStringInvalidRange;
break;
case CodeParameterIsReadOnly:
realReasonString = RtspReasonStringParameterIsReadOnly;
break;
case CodeAggregateOperationNotAllowed:
realReasonString =
RtspReasonStringAggregateOperationNotAllowed;
break;
case CodeOnlyAggregateOperationAllowed:
realReasonString =
RtspReasonStringOnlyAggregateOperationAllowed;
break;
case CodeUnsupportedTransport:
realReasonString = RtspReasonStringUnsupportedTransport;
break;
case CodeDestinationUnreachable:
realReasonString = RtspReasonStringDestinationUnreachable;
break;
case CodeUnsupportedClient:
realReasonString = RtspReasonStringUnsupportedClient;
break;
case CodeInternalServerError:
realReasonString = RtspReasonStringInternalServerError;
break;
case CodeNotImplemented:
realReasonString = RtspReasonStringNotImplemented;
break;
case CodeBadGateway:
realReasonString = RtspReasonStringBadGateway;
break;
case CodeServiceUnavailable:
realReasonString = RtspReasonStringServiceUnavailable;
break;
case CodeGatewayTimeout:
realReasonString = RtspReasonStringGatewayTimeout;
break;
case CodeRTSPVersionNotSupported:
realReasonString = RtspReasonStringRTSPVersionNotSupported;
break;
case CodeOptionNotSupported:
realReasonString = RtspReasonStringOptionNotSupported;
break;
case CodeParameterNotUnderstood:
realReasonString = RtspReasonStringParameterNotUnderstood;
break;
default:
// no string was found, since code is unknown...
;;;
}
if (realReasonString.length())
{
oscl_memcpy(fullRequestBufferSpace, realReasonString.c_str(), realReasonString.length());
fullRequestBufferSpace += realReasonString.length();
fullRequestBufferSizeUsed += realReasonString.length();
}
}
break;
}
case RTSPRequestMsg:
{
if (METHOD_BINARY_DATA == method)
{ // it's interleaved stuff
// leading dollar
*(fullRequestBufferSpace++) = CHAR_DOLLAR;
// 8-bit channel-id from the content-type
*(fullRequestBufferSpace++) = contentType.c_str()[0];
// 16-bit content length, in network byte order
*(fullRequestBufferSpace++) = char((contentLength & 0xFF00) >> 8);
*(fullRequestBufferSpace++) = char((contentLength & 0xFF));
*fullRequestBufferSpace = CHAR_NULL;
fullRequestBufferSizeUsed = 4;
fullRequestPLS = fullRequestBuffer;
return true;
}
// okay, it's a normal request
// do the method
if (method >= METHOD_NUM_ENTRIES)
{ // method unknown
return false;
}
uint32 method_strlen = oscl_strlen(RtspMethodStringPLSS[method]);
oscl_memcpy(fullRequestBufferSpace,
RtspMethodStringPLSS[method],
method_strlen
);
fullRequestBufferSpace += method_strlen;
*(fullRequestBufferSpace++) = CHAR_SPACE;
fullRequestBufferSizeUsed += method_strlen + 1;
// do the URI
oscl_memcpy(fullRequestBufferSpace,
originalURI.c_str(),
originalURI.length()
);
fullRequestBufferSpace += originalURI.length();
*(fullRequestBufferSpace++) = CHAR_SPACE;
fullRequestBufferSizeUsed += originalURI.length() + 1;
// do the RTSP version
#ifdef SIMPLE_HTTP_SUPPORT
if ((method == METHOD_GET) || (method == METHOD_POST))
{
oscl_memcpy(fullRequestBufferSpace,
HTTPVersion_1_0_String,
HTTPVersionString_len
);
}
else
#endif
oscl_memcpy(fullRequestBufferSpace,
RTSPVersionString,
RTSPVersionString_len
);
fullRequestBufferSpace += RTSPVersionString_len;
fullRequestBufferSizeUsed += RTSPVersionString_len;
break;
}
default:
{ // cannot encode an unknown type of message
return false;
}
}
// add the final newline to the first string
*(fullRequestBufferSpace++) = CHAR_CR;
*(fullRequestBufferSpace++) = CHAR_LF;
fullRequestBufferSizeUsed += 2;
// add the shortcut fields
if ((method != METHOD_GET) && (method != METHOD_POST))
{
if (cseqIsSet)
{
// The Symbian version of oscl_snprintf does not support %ld format, should use %d or %u instead.
// Since cseq is an uint32 it's ok to use %u.
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "CSeq: %u%c%c",
cseq, CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
else
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "CSeq: %c%c",
CHAR_CR, CHAR_LF);
int addSize = 8;
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
}
if (RTSPResponseMsg == msgType)
{
TimeValue current_time;
const int DATE_BUFSIZE = 29;
char tmp[DATE_BUFSIZE+1];
int max_len = RTSP_MAX_FULL_REQUEST_SIZE -
fullRequestBufferSizeUsed;
if (max_len < DATE_BUFSIZE + 8)
{
// not enough room ("8" represents the size of Date: CRLF)
return false;
}
current_time.get_rfc822_gmtime_str(DATE_BUFSIZE + 1, tmp);
if (tmp[0] != '\0')
{
// date string is not empty
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Date: %s%c%c",
tmp, CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
}
if (bufferSizeIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Buffersize: %u%c%c",
bufferSize, CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (sessionIdIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Session: %s%c%c",
sessionId.c_str(), CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
/*
#ifdef RTSP_PLAYLIST_SUPPORT
// hard code these for now, later should have a general supported field build that adds on entries as needed
if(methodEosIsSet)
{
if(comPvServerPlaylistIsSet)
{
oscl_snprintf( fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE-1,
"Supported: com.pv.server_playlist,method.eos%c%c",
CHAR_CR, CHAR_LF );
}
else
{
oscl_snprintf( fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE-1,
"Supported: method.eos%c%c",
CHAR_CR, CHAR_LF );
}
}
int addSize = oscl_strlen( fullRequestBufferSpace );
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
#endif
*/
if (userAgentIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "User-Agent: %s%c%c",
userAgent.c_str(), CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (acceptIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Accept: %s%c%c",
accept.c_str(), CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (requireIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Require: %s%c%c",
require.c_str(), CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (contentTypeIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Type: %s%c%c",
contentType.c_str(), CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (contentBaseMode != NO_CONTENT_BASE)
{
if (contentBaseMode == INCLUDE_TRAILING_SLASH &&
*(contentBase.c_str() + oscl_strlen(contentBase.c_str()) - 1) != CHAR_SLASH)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Base: %s%c%c%c",
contentBase.c_str(), CHAR_SLASH, CHAR_CR, CHAR_LF);
}
else
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Base: %s%c%c",
contentBase.c_str(), CHAR_CR, CHAR_LF);
}
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (contentLengthIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Length: %u%c%c",
contentLength, CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
if (numOfTransportEntries)
{
oscl_strncpy(fullRequestBufferSpace, "Transport: ", 11);
fullRequestBufferSpace[11] = NULL_TERM_CHAR;
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
for (uint ii = 0; ii < numOfTransportEntries; ++ii)
{
composeTransport(fullRequestBufferSpace, transport + ii);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
if (ii < numOfTransportEntries - 1)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ",");
fullRequestBufferSizeUsed += 1;
fullRequestBufferSpace += 1;
}
}
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%c%c", CHAR_CR, CHAR_LF);
fullRequestBufferSizeUsed += 2;
fullRequestBufferSpace += 2;
}
if (rangeIsSet)
{
int addSize;
unsigned int max_len = RTSP_MAX_FULL_REQUEST_SIZE -
fullRequestBufferSizeUsed;
if (!compose_RTSP_string(fullRequestBufferSpace,
max_len,
range, addSize))
{
return false;
}
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
// put a null terminator on the end
*fullRequestBufferSpace = '\0';
}
// compose the RTP Info
//
if (numOfRtpInfoEntries)
{
oscl_strncpy(fullRequestBufferSpace, "RTP-Info: ", 10);
fullRequestBufferSpace[10] = NULL_TERM_CHAR;
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
for (uint32 ii = 0; ii < numOfRtpInfoEntries; ++ii)
{
bool somethingIsPresent = false;
if (ii)
{
// put some leading whitespace on the line
oscl_strncpy(fullRequestBufferSpace, " ", 2);
fullRequestBufferSpace[2] = NULL_TERM_CHAR;
fullRequestBufferSizeUsed += 2;
fullRequestBufferSpace += 2;
}
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
if (rtpInfo[ii].urlIsSet)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "url=%s", rtpInfo[ii].url.c_str());
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
somethingIsPresent = true;
}
if (rtpInfo[ii].seqIsSet)
{
if (somethingIsPresent)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ";seq=%d", rtpInfo[ii].seq);
}
else
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "seq=%d", rtpInfo[ii].seq);
}
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
somethingIsPresent = true;
}
if (rtpInfo[ii].rtptimeIsSet)
{
if (somethingIsPresent)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ";rtptime=%u", rtpInfo[ii].rtptime);
}
else
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "rtptime=%u", rtpInfo[ii].rtptime);
}
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
somethingIsPresent = true;
}
if (ii < numOfRtpInfoEntries - 1)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ",%c%c", CHAR_CR, CHAR_LF);
fullRequestBufferSizeUsed += 3;
fullRequestBufferSpace += 3;
}
}
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%c%c", CHAR_CR, CHAR_LF);
fullRequestBufferSizeUsed += 2;
fullRequestBufferSpace += 2;
}
// add the outstanding fields
for (uint32 jj = 0; jj < numPtrFields; ++jj)
{
oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%s: %s%c%c",
fieldKeys[ jj ].c_str(), fieldVals[ jj ].c_str(), CHAR_CR, CHAR_LF);
int addSize = oscl_strlen(fullRequestBufferSpace);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
#ifdef ASF_STREAMING
if (XMLIsSet)
{
// now, add a newline before the XML message
*(fullRequestBufferSpace++) = CHAR_CR;
*(fullRequestBufferSpace++) = CHAR_LF;
fullRequestBufferSizeUsed += 2;
int addSize = strlen(XMLBufferPtr);
oscl_memcpy(fullRequestBufferSpace, XMLBufferPtr, addSize);
fullRequestBufferSizeUsed += addSize;
fullRequestBufferSpace += addSize;
}
#endif
// now, add the final newline to the whole message
*(fullRequestBufferSpace++) = CHAR_CR;
*(fullRequestBufferSpace++) = CHAR_LF;
fullRequestBufferSizeUsed += 2;
*(fullRequestBufferSpace) = CHAR_NULL;
// finally, set up to return
fullRequestPLS = fullRequestBuffer;
return true;
}
OSCL_EXPORT_REF void
RTSPOutgoingMessage::bind(const RTSPIncomingMessage & incoming)
{
StrCSumPtrLen timeStampName("Timestamp");
cseqIsSet = incoming.cseqIsSet;
cseq = incoming.cseq;
sessionIdIsSet = incoming.sessionIdIsSet;
sessionId = incoming.sessionId;
const StrPtrLen * timeStampVal;
if (NULL != (timeStampVal = incoming.queryField(timeStampName)))
{
addField(&timeStampName, timeStampVal);
}
}
void
RTSPOutgoingMessage::composeTransport(char* trans, RtspTransport* rtspTrans)
{
const int tmp_size = 64;
char tmp[tmp_size];
if (rtspTrans->protocolIsSet)
{
if (rtspTrans->protocol == RtspTransport::RTP_PROTOCOL)
{
oscl_strcat(trans, "RTP");
}
else if (rtspTrans->protocol == RtspTransport::RDT_PROTOCOL)
{
oscl_strcat(trans, "x-pn-tng");
}
}
if (rtspTrans->profileIsSet)
{
if (rtspTrans->profile == RtspTransport::AVP_PROFILE)
{
oscl_strcat(trans, "/AVP");
}
else if (rtspTrans->profile == RtspTransport::TCP_PROFILE)
{//Real
oscl_strcat(trans, "/tcp");
}
}
if (rtspTrans->transportTypeIsSet)
{
if (rtspTrans->transportType == RtspTransport::UDP_TRANSPORT)
{
oscl_strcat(trans, "/UDP");
}
else if (rtspTrans->transportType == RtspTransport::TCP_TRANSPORT)
{
oscl_strcat(trans, "/TCP");
}
}
if (rtspTrans->deliveryIsSet)
{
if (rtspTrans->delivery == RtspTransport::UNICAST_DELIVERY)
{
oscl_strcat(trans, ";unicast");
}
if (rtspTrans->delivery == RtspTransport::MULTICAST_DELIVERY)
{
oscl_strcat(trans, ";multicast");
}
}
if (rtspTrans->destinationIsSet)
{
if (rtspTrans->destination.c_str() && rtspTrans->destination.length())
{
oscl_strcat(trans, rtspTrans->destination.c_str());
}
}
if (rtspTrans->channelIsSet)
{
oscl_snprintf(tmp, 63, ";interleaved=%d-%d", rtspTrans->channel1,
rtspTrans->channel2);
oscl_strcat(trans, tmp);
}
if (rtspTrans->client_portIsSet)
#ifdef ASF_STREAMING
if (rtspTrans->client_port2 == NULL)
{
oscl_snprintf(tmp, 63, ";client_port=%d", rtspTrans->client_port1);
oscl_strcat(trans, tmp);
}
else
#endif
{
oscl_snprintf(tmp, 63, ";client_port=%d-%d", rtspTrans->client_port1, rtspTrans->client_port2);
oscl_strcat(trans, tmp);
}
if (rtspTrans->server_portIsSet)
{
oscl_snprintf(tmp, 63, ";server_port=%d-%d", rtspTrans->server_port1, rtspTrans->server_port2);
oscl_strcat(trans, tmp);
}
if (rtspTrans->modeIsSet)
{
if (rtspTrans->mode.play_mode)
{
oscl_strncpy(tmp, ";mode=play", 9);
tmp[9] = NULL_TERM_CHAR;
oscl_strcat(trans, tmp);
}
if (rtspTrans->mode.record_mode)
{
oscl_strncpy(tmp, ";mode=record", 11);
tmp[11] = NULL_TERM_CHAR;
oscl_strcat(trans, tmp);
if (rtspTrans->append)
{
oscl_strncpy(tmp, ";append", 6);
tmp[6] = NULL_TERM_CHAR;
oscl_strcat(trans, tmp);
}
}
}
if (rtspTrans->ttlIsSet)
{
oscl_snprintf(tmp, 63, ";ttl=%d", rtspTrans->ttl);
oscl_strcat(trans, tmp);
}
if (rtspTrans->layersIsSet)
{
oscl_snprintf(tmp, 63, ";layers=%u", rtspTrans->layers);
oscl_strcat(trans, tmp);
}
if (rtspTrans->ssrcIsSet)
{
oscl_snprintf(tmp, 63, ";ssrc=%.8x", rtspTrans->ssrc);
oscl_strcat(trans, tmp);
}
}