Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "oscl_snprintf.h"
     19 #include "rtsp_par_com.h"
     20 #include "rtsp_range_utils.h"
     21 #include "oscl_time.h"
     22 
     23 
     24 
     25 OSCL_EXPORT_REF void
     26 RTSPOutgoingMessage::reset()
     27 {
     28     RTSPGenericMessage::reset();
     29 
     30     fullRequestBufferSizeUsed = 0;
     31     fullRequestBufferSpace = fullRequestBuffer;
     32 
     33     boundMessage = NULL;
     34 }
     35 
     36 OSCL_EXPORT_REF StrPtrLen *
     37 RTSPOutgoingMessage::retrieveComposedBuffer()
     38 {
     39     return &fullRequestPLS;
     40 }
     41 
     42 OSCL_EXPORT_REF bool
     43 RTSPOutgoingMessage::addField(
     44     StrCSumPtrLen * newFieldName,
     45     const StrPtrLen *    newFieldValue
     46 )
     47 {
     48     StrPtrLen * fieldVal = const_cast<StrPtrLen *>(queryField(* newFieldName));
     49 
     50     uint32  extraSize;
     51 
     52     // check if this field already exists in the message
     53     //
     54     if (NULL == fieldVal)
     55     { // this field is new to the message
     56 
     57         // check that there are enough pointers
     58         if (RTSP_MAX_NUMBER_OF_FIELDS == numPtrFields)
     59         {
     60             return false;
     61         }
     62 
     63         // check for the extra size
     64         extraSize = newFieldName->length() + newFieldValue->length() + 2;
     65         if (RTSP_MAX_FULL_REQUEST_SIZE < secondaryBufferSizeUsed + extraSize)
     66         {
     67             return false;
     68         }
     69 
     70         // oscl_memcpy is unsafe for overlaps, but source and target memory come from
     71         // different sources
     72         //
     73         oscl_memcpy(secondaryBufferSpace, newFieldName->c_str(),
     74                     newFieldName->length() + 1);
     75         oscl_memcpy(secondaryBufferSpace + newFieldName->length() + 1,
     76                     newFieldValue->c_str(), newFieldValue->length() + 1);
     77 
     78         // save the incoming structures, but reset pointers to their new home in the
     79         // secondary buffer
     80 
     81         fieldKeys[ numPtrFields ].setPtrLen(secondaryBufferSpace,
     82                                             newFieldName->length());
     83         fieldVals[ numPtrFields ].setPtrLen(
     84             secondaryBufferSpace + newFieldName->length() + 1,
     85             newFieldValue->length()
     86         );
     87 
     88         // pop up the number of used pointers
     89         //
     90         ++ numPtrFields;
     91 
     92         // do buffer accounting
     93         //
     94     }
     95     else
     96     { // this field is known to the message, we just have to replace its value
     97 
     98         // check for the extra size
     99         extraSize = newFieldValue->length() + 1;
    100         if (RTSP_MAX_FULL_REQUEST_SIZE < secondaryBufferSizeUsed + extraSize)
    101         {
    102             return false;
    103         }
    104 
    105         // oscl_memcpy is unsafe for overlaps, but source and target memory come from
    106         // different sources
    107         //
    108         oscl_memcpy(secondaryBufferSpace, newFieldValue->c_str(),
    109                     newFieldValue->length() + 1);
    110 
    111         // save the incoming structures, but reset pointers to their new home in the
    112         // secondary buffer
    113 
    114         fieldVal->setPtrLen(secondaryBufferSpace, newFieldValue->length());
    115     }
    116 
    117     secondaryBufferSizeUsed += extraSize;
    118     secondaryBufferSpace = secondaryBuffer + secondaryBufferSizeUsed;
    119 
    120     return true;
    121 }
    122 
    123 OSCL_EXPORT_REF bool
    124 RTSPOutgoingMessage::addField(
    125     StrCSumPtrLen * newFieldName,
    126     const char *      newValue
    127 )
    128 {
    129     StrPtrLen valuePLS(newValue);
    130 
    131     return addField(newFieldName, &valuePLS);
    132 }
    133 
    134 OSCL_EXPORT_REF bool
    135 RTSPOutgoingMessage::compose()
    136 {
    137 
    138 
    139 
    140     // compose the first line
    141     //
    142     switch (msgType)
    143     {
    144         case RTSPResponseMsg:
    145 
    146         {
    147             // RTSP version
    148             //
    149             oscl_memcpy(fullRequestBuffer, RTSPVersionString, RTSPVersionString_len);
    150             fullRequestBufferSpace += RTSPVersionString_len;
    151 
    152             *(fullRequestBufferSpace++) = ' ';
    153 
    154 
    155             // Status code
    156             //
    157             oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%d", statusCode);
    158 
    159             // resync the pointer and size used
    160             fullRequestBufferSizeUsed = oscl_strlen(fullRequestBufferSpace);
    161             fullRequestBufferSpace += fullRequestBufferSizeUsed;
    162             *(fullRequestBufferSpace++) = ' ';
    163             fullRequestBufferSizeUsed += 1 + RTSPVersionString_len + 1;
    164 
    165             if (0 != reasonString.length())
    166             {
    167                 // user specified his own string
    168                 //
    169                 oscl_memcpy(fullRequestBufferSpace, reasonString.c_str(),
    170                             reasonString.length());
    171 
    172                 fullRequestBufferSpace += reasonString.length();
    173                 fullRequestBufferSizeUsed += reasonString.length();
    174             }
    175             else
    176             {
    177                 StrPtrLen  realReasonString ;
    178 
    179                 // user wants the built-in default
    180                 //
    181                 switch (statusCode)
    182                 {
    183                     case CodeContinue:
    184 
    185                         realReasonString =  RtspReasonStringContinue;
    186 
    187                         break;
    188 
    189                     case CodeOK:
    190 
    191                         realReasonString =  RtspReasonStringOK;
    192 
    193                         break;
    194 
    195                     case CodeCreated:
    196                         realReasonString =  RtspReasonStringCreated;
    197 
    198                         break;
    199 
    200                     case CodeLowOnStorageSpace:
    201                         realReasonString =  RtspReasonStringLowOnStorageSpace;
    202 
    203                         break;
    204 
    205                     case CodeMultipleChoices:
    206                         realReasonString =  RtspReasonStringMultipleChoices;
    207 
    208                         break;
    209 
    210                     case CodeMovedPermanently:
    211                         realReasonString =  RtspReasonStringMovedPermanently;
    212 
    213                         break;
    214 
    215                     case CodeMovedTemporarily:
    216                         realReasonString =  RtspReasonStringMovedTemporarily;
    217 
    218                         break;
    219 
    220                     case CodeSeeOther:
    221                         realReasonString =  RtspReasonStringSeeOther;
    222 
    223                         break;
    224 
    225                     case CodeNotModified:
    226                         realReasonString =  RtspReasonStringNotModified;
    227 
    228                         break;
    229 
    230                     case CodeUseProxy:
    231                         realReasonString =  RtspReasonStringUseProxy;
    232 
    233                         break;
    234 
    235                     case CodeBadRequest:
    236                         realReasonString =  RtspReasonStringBadRequest;
    237 
    238                         break;
    239 
    240                     case CodeUnauthorized:
    241                         realReasonString =  RtspReasonStringUnauthorized;
    242 
    243                         break;
    244 
    245                     case CodePaymentRequired:
    246                         realReasonString =  RtspReasonStringPaymentRequired;
    247 
    248                         break;
    249 
    250                     case CodeForbidden:
    251                         realReasonString =  RtspReasonStringForbidden;
    252 
    253                         break;
    254 
    255                     case CodeNotFound:
    256                         realReasonString =  RtspReasonStringNotFound;
    257 
    258                         break;
    259 
    260                     case CodeMethodNotAllowed:
    261                         realReasonString =  RtspReasonStringMethodNotAllowed;
    262 
    263                         break;
    264 
    265                     case CodeNotAcceptable:
    266                         realReasonString =  RtspReasonStringNotAcceptable;
    267 
    268                         break;
    269 
    270                     case CodeProxyAuthenticationRequired:
    271                         realReasonString =
    272                             RtspReasonStringProxyAuthenticationRequired;
    273 
    274                         break;
    275 
    276                     case CodeRequestTimeOut:
    277                         realReasonString =  RtspReasonStringRequestTimeOut;
    278 
    279                         break;
    280 
    281                     case CodeGone:
    282                         realReasonString =  RtspReasonStringGone;
    283 
    284                         break;
    285 
    286                     case CodeLengthRequired:
    287                         realReasonString =  RtspReasonStringLengthRequired;
    288 
    289                         break;
    290 
    291                     case CodePreconditionFailed:
    292                         realReasonString =  RtspReasonStringPreconditionFailed;
    293 
    294                         break;
    295 
    296                     case CodeRequestEntityTooLarge:
    297                         realReasonString =
    298                             RtspReasonStringRequestEntityTooLarge;
    299 
    300                         break;
    301 
    302                     case CodeRequestURITooLarge:
    303                         realReasonString =  RtspReasonStringRequestURITooLarge;
    304 
    305                         break;
    306 
    307                     case CodeUnsupportedMediaType:
    308                         realReasonString =  RtspReasonStringUnsupportedMediaType;
    309 
    310                         break;
    311 
    312                     case CodeSessionNotFound:
    313                         realReasonString =  RtspReasonStringSessionNotFound;
    314 
    315                         break;
    316 
    317                     case CodeMethodNotValidInThisState:
    318                         realReasonString =  RtspReasonStringMethodNotValidInThisState;
    319 
    320                         break;
    321 
    322                     case CodeHeaderFieldNotValidForResource:
    323                         realReasonString =
    324                             RtspReasonStringHeaderFieldNotValidForResource;
    325 
    326                         break;
    327 
    328                     case CodeInvalidRange:
    329                         realReasonString =  RtspReasonStringInvalidRange;
    330 
    331                         break;
    332 
    333                     case CodeParameterIsReadOnly:
    334                         realReasonString =  RtspReasonStringParameterIsReadOnly;
    335 
    336                         break;
    337 
    338                     case CodeAggregateOperationNotAllowed:
    339                         realReasonString =
    340                             RtspReasonStringAggregateOperationNotAllowed;
    341 
    342                         break;
    343 
    344                     case CodeOnlyAggregateOperationAllowed:
    345                         realReasonString =
    346                             RtspReasonStringOnlyAggregateOperationAllowed;
    347 
    348                         break;
    349 
    350                     case CodeUnsupportedTransport:
    351                         realReasonString =  RtspReasonStringUnsupportedTransport;
    352 
    353                         break;
    354 
    355                     case CodeDestinationUnreachable:
    356                         realReasonString =  RtspReasonStringDestinationUnreachable;
    357 
    358                         break;
    359 
    360                     case CodeUnsupportedClient:
    361                         realReasonString =  RtspReasonStringUnsupportedClient;
    362 
    363                         break;
    364 
    365                     case CodeInternalServerError:
    366                         realReasonString =  RtspReasonStringInternalServerError;
    367 
    368                         break;
    369 
    370                     case CodeNotImplemented:
    371                         realReasonString =  RtspReasonStringNotImplemented;
    372 
    373                         break;
    374 
    375                     case CodeBadGateway:
    376                         realReasonString =  RtspReasonStringBadGateway;
    377 
    378                         break;
    379 
    380                     case CodeServiceUnavailable:
    381                         realReasonString =  RtspReasonStringServiceUnavailable;
    382 
    383                         break;
    384 
    385                     case CodeGatewayTimeout:
    386                         realReasonString =  RtspReasonStringGatewayTimeout;
    387 
    388                         break;
    389 
    390                     case CodeRTSPVersionNotSupported:
    391                         realReasonString =  RtspReasonStringRTSPVersionNotSupported;
    392 
    393                         break;
    394 
    395                     case CodeOptionNotSupported:
    396                         realReasonString =  RtspReasonStringOptionNotSupported;
    397 
    398                         break;
    399 
    400                     case CodeParameterNotUnderstood:
    401                         realReasonString =  RtspReasonStringParameterNotUnderstood;
    402 
    403                         break;
    404 
    405                     default:
    406                         // no string was found, since code is unknown...
    407                         ;;;
    408                 }
    409 
    410                 if (realReasonString.length())
    411                 {
    412                     oscl_memcpy(fullRequestBufferSpace, realReasonString.c_str(), realReasonString.length());
    413 
    414                     fullRequestBufferSpace += realReasonString.length();
    415                     fullRequestBufferSizeUsed += realReasonString.length();
    416                 }
    417             }
    418 
    419             break;
    420         }
    421 
    422 
    423         case RTSPRequestMsg:
    424         {
    425             if (METHOD_BINARY_DATA == method)
    426             { // it's interleaved stuff
    427 
    428                 // leading dollar
    429                 *(fullRequestBufferSpace++) = CHAR_DOLLAR;
    430 
    431                 // 8-bit channel-id from the content-type
    432                 *(fullRequestBufferSpace++) = contentType.c_str()[0];
    433 
    434                 // 16-bit content length, in network byte order
    435                 *(fullRequestBufferSpace++) = char((contentLength & 0xFF00) >> 8);
    436                 *(fullRequestBufferSpace++) = char((contentLength & 0xFF));
    437 
    438                 *fullRequestBufferSpace = CHAR_NULL;
    439 
    440                 fullRequestBufferSizeUsed = 4;
    441 
    442                 fullRequestPLS = fullRequestBuffer;
    443 
    444                 return true;
    445             }
    446 
    447             // okay, it's a normal request
    448 
    449             // do the method
    450             if (method >= METHOD_NUM_ENTRIES)
    451             { // method unknown
    452                 return false;
    453             }
    454 
    455             uint32 method_strlen = oscl_strlen(RtspMethodStringPLSS[method]);
    456             oscl_memcpy(fullRequestBufferSpace,
    457                         RtspMethodStringPLSS[method],
    458                         method_strlen
    459                        );
    460             fullRequestBufferSpace += method_strlen;
    461             *(fullRequestBufferSpace++) = CHAR_SPACE;
    462             fullRequestBufferSizeUsed += method_strlen + 1;
    463 
    464             // do the URI
    465 
    466             oscl_memcpy(fullRequestBufferSpace,
    467                         originalURI.c_str(),
    468                         originalURI.length()
    469                        );
    470             fullRequestBufferSpace += originalURI.length();
    471             *(fullRequestBufferSpace++) = CHAR_SPACE;
    472             fullRequestBufferSizeUsed += originalURI.length() + 1;
    473 
    474             // do the RTSP version
    475 #ifdef SIMPLE_HTTP_SUPPORT
    476             if ((method == METHOD_GET) || (method == METHOD_POST))
    477             {
    478                 oscl_memcpy(fullRequestBufferSpace,
    479                             HTTPVersion_1_0_String,
    480                             HTTPVersionString_len
    481                            );
    482             }
    483             else
    484 #endif
    485                 oscl_memcpy(fullRequestBufferSpace,
    486                             RTSPVersionString,
    487                             RTSPVersionString_len
    488                            );
    489             fullRequestBufferSpace += RTSPVersionString_len;
    490             fullRequestBufferSizeUsed += RTSPVersionString_len;
    491 
    492             break;
    493         }
    494 
    495         default:
    496         {   // cannot encode an unknown type of message
    497 
    498             return false;
    499         }
    500     }
    501 
    502 
    503     // add the final newline to the first string
    504     *(fullRequestBufferSpace++) = CHAR_CR;
    505     *(fullRequestBufferSpace++) = CHAR_LF;
    506     fullRequestBufferSizeUsed += 2;
    507 
    508 
    509     // add the shortcut fields
    510 
    511     if ((method != METHOD_GET) && (method != METHOD_POST))
    512     {
    513         if (cseqIsSet)
    514         {
    515             // The Symbian version of oscl_snprintf does not support %ld format, should use %d or %u instead.
    516             // Since cseq is an uint32 it's ok to use %u.
    517             oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "CSeq: %u%c%c",
    518                           cseq, CHAR_CR, CHAR_LF);
    519             int addSize = oscl_strlen(fullRequestBufferSpace);
    520             fullRequestBufferSizeUsed += addSize;
    521             fullRequestBufferSpace += addSize;
    522         }
    523         else
    524         {
    525             oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "CSeq: %c%c",
    526                           CHAR_CR, CHAR_LF);
    527             int addSize = 8;
    528             fullRequestBufferSizeUsed += addSize;
    529             fullRequestBufferSpace += addSize;
    530         }
    531     }
    532 
    533     if (RTSPResponseMsg == msgType)
    534     {
    535         TimeValue current_time;
    536         const int DATE_BUFSIZE = 29;
    537         char tmp[DATE_BUFSIZE+1];
    538 
    539         int max_len =  RTSP_MAX_FULL_REQUEST_SIZE -
    540                        fullRequestBufferSizeUsed;
    541         if (max_len < DATE_BUFSIZE + 8)
    542         {
    543             // not enough room ("8" represents the size of Date: CRLF)
    544             return false;
    545         }
    546         current_time.get_rfc822_gmtime_str(DATE_BUFSIZE + 1, tmp);
    547         if (tmp[0] != '\0')
    548         {
    549             // date string is not empty
    550             oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Date: %s%c%c",
    551                           tmp, CHAR_CR, CHAR_LF);
    552             int addSize = oscl_strlen(fullRequestBufferSpace);
    553             fullRequestBufferSizeUsed += addSize;
    554             fullRequestBufferSpace += addSize;
    555         }
    556 
    557     }
    558 
    559     if (bufferSizeIsSet)
    560     {
    561         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Buffersize: %u%c%c",
    562                       bufferSize, CHAR_CR, CHAR_LF);
    563         int addSize = oscl_strlen(fullRequestBufferSpace);
    564         fullRequestBufferSizeUsed += addSize;
    565         fullRequestBufferSpace += addSize;
    566     }
    567 
    568     if (sessionIdIsSet)
    569     {
    570         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Session: %s%c%c",
    571                       sessionId.c_str(), CHAR_CR, CHAR_LF);
    572         int addSize = oscl_strlen(fullRequestBufferSpace);
    573         fullRequestBufferSizeUsed += addSize;
    574         fullRequestBufferSpace += addSize;
    575     }
    576 
    577     /*
    578     #ifdef RTSP_PLAYLIST_SUPPORT
    579     // hard code these for now, later should have a general supported field build that adds on entries as needed
    580     if(methodEosIsSet)
    581     {
    582         if(comPvServerPlaylistIsSet)
    583         {
    584             oscl_snprintf( fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE-1,
    585                 "Supported: com.pv.server_playlist,method.eos%c%c",
    586                 CHAR_CR, CHAR_LF );
    587         }
    588         else
    589         {
    590             oscl_snprintf( fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE-1,
    591                 "Supported: method.eos%c%c",
    592                 CHAR_CR, CHAR_LF );
    593         }
    594     }
    595     int addSize = oscl_strlen( fullRequestBufferSpace );
    596     fullRequestBufferSizeUsed += addSize;
    597     fullRequestBufferSpace += addSize;
    598     #endif
    599     */
    600     if (userAgentIsSet)
    601     {
    602         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "User-Agent: %s%c%c",
    603                       userAgent.c_str(), CHAR_CR, CHAR_LF);
    604         int addSize = oscl_strlen(fullRequestBufferSpace);
    605         fullRequestBufferSizeUsed += addSize;
    606         fullRequestBufferSpace += addSize;
    607     }
    608 
    609     if (acceptIsSet)
    610     {
    611         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Accept: %s%c%c",
    612                       accept.c_str(), CHAR_CR, CHAR_LF);
    613         int addSize = oscl_strlen(fullRequestBufferSpace);
    614         fullRequestBufferSizeUsed += addSize;
    615         fullRequestBufferSpace += addSize;
    616     }
    617 
    618     if (requireIsSet)
    619     {
    620         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Require: %s%c%c",
    621                       require.c_str(), CHAR_CR, CHAR_LF);
    622         int addSize = oscl_strlen(fullRequestBufferSpace);
    623         fullRequestBufferSizeUsed += addSize;
    624         fullRequestBufferSpace += addSize;
    625     }
    626 
    627     if (contentTypeIsSet)
    628     {
    629         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Type: %s%c%c",
    630                       contentType.c_str(), CHAR_CR, CHAR_LF);
    631         int addSize = oscl_strlen(fullRequestBufferSpace);
    632         fullRequestBufferSizeUsed += addSize;
    633         fullRequestBufferSpace += addSize;
    634     }
    635 
    636     if (contentBaseMode != NO_CONTENT_BASE)
    637     {
    638         if (contentBaseMode == INCLUDE_TRAILING_SLASH &&
    639                 *(contentBase.c_str() + oscl_strlen(contentBase.c_str()) - 1) != CHAR_SLASH)
    640         {
    641             oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Base: %s%c%c%c",
    642                           contentBase.c_str(), CHAR_SLASH, CHAR_CR, CHAR_LF);
    643         }
    644         else
    645         {
    646             oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Base: %s%c%c",
    647                           contentBase.c_str(), CHAR_CR, CHAR_LF);
    648         }
    649         int addSize = oscl_strlen(fullRequestBufferSpace);
    650         fullRequestBufferSizeUsed += addSize;
    651         fullRequestBufferSpace += addSize;
    652     }
    653 
    654     if (contentLengthIsSet)
    655     {
    656         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "Content-Length: %u%c%c",
    657                       contentLength, CHAR_CR, CHAR_LF);
    658         int addSize = oscl_strlen(fullRequestBufferSpace);
    659         fullRequestBufferSizeUsed += addSize;
    660         fullRequestBufferSpace += addSize;
    661     }
    662 
    663     if (numOfTransportEntries)
    664     {
    665         oscl_strncpy(fullRequestBufferSpace, "Transport: ", 11);
    666         fullRequestBufferSpace[11] = NULL_TERM_CHAR;
    667         int addSize = oscl_strlen(fullRequestBufferSpace);
    668         fullRequestBufferSizeUsed += addSize;
    669         fullRequestBufferSpace += addSize;
    670 
    671         for (uint ii = 0; ii < numOfTransportEntries; ++ii)
    672         {
    673             composeTransport(fullRequestBufferSpace, transport + ii);
    674             int addSize = oscl_strlen(fullRequestBufferSpace);
    675             fullRequestBufferSizeUsed += addSize;
    676             fullRequestBufferSpace += addSize;
    677 
    678             if (ii < numOfTransportEntries - 1)
    679             {
    680                 oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ",");
    681                 fullRequestBufferSizeUsed += 1;
    682                 fullRequestBufferSpace += 1;
    683             }
    684         }
    685 
    686         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%c%c", CHAR_CR, CHAR_LF);
    687         fullRequestBufferSizeUsed += 2;
    688         fullRequestBufferSpace += 2;
    689 
    690     }
    691 
    692     if (rangeIsSet)
    693     {
    694         int addSize;
    695         unsigned int max_len = RTSP_MAX_FULL_REQUEST_SIZE -
    696                                fullRequestBufferSizeUsed;
    697         if (!compose_RTSP_string(fullRequestBufferSpace,
    698                                  max_len,
    699                                  range, addSize))
    700         {
    701             return false;
    702         }
    703         fullRequestBufferSizeUsed += addSize;
    704         fullRequestBufferSpace += addSize;
    705         // put a null terminator on the end
    706         *fullRequestBufferSpace = '\0';
    707 
    708     }
    709 
    710     // compose the RTP Info
    711     //
    712     if (numOfRtpInfoEntries)
    713     {
    714         oscl_strncpy(fullRequestBufferSpace, "RTP-Info: ", 10);
    715         fullRequestBufferSpace[10] = NULL_TERM_CHAR;
    716         int addSize = oscl_strlen(fullRequestBufferSpace);
    717         fullRequestBufferSizeUsed += addSize;
    718         fullRequestBufferSpace += addSize;
    719         for (uint32 ii = 0; ii < numOfRtpInfoEntries; ++ii)
    720         {
    721             bool somethingIsPresent = false;
    722 
    723             if (ii)
    724             {
    725                 // put some leading whitespace on the line
    726                 oscl_strncpy(fullRequestBufferSpace, "  ", 2);
    727                 fullRequestBufferSpace[2] = NULL_TERM_CHAR;
    728                 fullRequestBufferSizeUsed += 2;
    729                 fullRequestBufferSpace += 2;
    730             }
    731 
    732             int addSize = oscl_strlen(fullRequestBufferSpace);
    733             fullRequestBufferSizeUsed += addSize;
    734             fullRequestBufferSpace += addSize;
    735             if (rtpInfo[ii].urlIsSet)
    736             {
    737                 oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "url=%s", rtpInfo[ii].url.c_str());
    738                 int addSize = oscl_strlen(fullRequestBufferSpace);
    739                 fullRequestBufferSizeUsed += addSize;
    740                 fullRequestBufferSpace += addSize;
    741                 somethingIsPresent = true;
    742             }
    743             if (rtpInfo[ii].seqIsSet)
    744             {
    745                 if (somethingIsPresent)
    746                 {
    747                     oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ";seq=%d", rtpInfo[ii].seq);
    748                 }
    749                 else
    750                 {
    751                     oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "seq=%d", rtpInfo[ii].seq);
    752                 }
    753                 int addSize = oscl_strlen(fullRequestBufferSpace);
    754                 fullRequestBufferSizeUsed += addSize;
    755                 fullRequestBufferSpace += addSize;
    756                 somethingIsPresent = true;
    757             }
    758             if (rtpInfo[ii].rtptimeIsSet)
    759             {
    760                 if (somethingIsPresent)
    761                 {
    762                     oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ";rtptime=%u", rtpInfo[ii].rtptime);
    763                 }
    764                 else
    765                 {
    766                     oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "rtptime=%u", rtpInfo[ii].rtptime);
    767                 }
    768                 int addSize = oscl_strlen(fullRequestBufferSpace);
    769                 fullRequestBufferSizeUsed += addSize;
    770                 fullRequestBufferSpace += addSize;
    771                 somethingIsPresent = true;
    772             }
    773 
    774             if (ii < numOfRtpInfoEntries - 1)
    775             {
    776                 oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, ",%c%c", CHAR_CR, CHAR_LF);
    777                 fullRequestBufferSizeUsed += 3;
    778                 fullRequestBufferSpace += 3;
    779             }
    780 
    781 
    782         }
    783         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%c%c", CHAR_CR, CHAR_LF);
    784         fullRequestBufferSizeUsed += 2;
    785         fullRequestBufferSpace += 2;
    786 
    787     }
    788 
    789     // add the outstanding fields
    790 
    791     for (uint32 jj = 0; jj < numPtrFields; ++jj)
    792     {
    793         oscl_snprintf(fullRequestBufferSpace, RTSP_MAX_FULL_REQUEST_SIZE - 1, "%s: %s%c%c",
    794                       fieldKeys[ jj ].c_str(), fieldVals[ jj ].c_str(), CHAR_CR, CHAR_LF);
    795 
    796         int addSize = oscl_strlen(fullRequestBufferSpace);
    797         fullRequestBufferSizeUsed += addSize;
    798         fullRequestBufferSpace += addSize;
    799     }
    800 
    801 #ifdef ASF_STREAMING
    802     if (XMLIsSet)
    803     {
    804         // now, add a newline before the XML message
    805         *(fullRequestBufferSpace++) = CHAR_CR;
    806         *(fullRequestBufferSpace++) = CHAR_LF;
    807         fullRequestBufferSizeUsed += 2;
    808 
    809         int addSize = strlen(XMLBufferPtr);
    810         oscl_memcpy(fullRequestBufferSpace, XMLBufferPtr, addSize);
    811         fullRequestBufferSizeUsed += addSize;
    812         fullRequestBufferSpace += addSize;
    813     }
    814 
    815 #endif
    816 
    817     // now, add the final newline to the whole message
    818     *(fullRequestBufferSpace++) = CHAR_CR;
    819     *(fullRequestBufferSpace++) = CHAR_LF;
    820     fullRequestBufferSizeUsed += 2;
    821 
    822     *(fullRequestBufferSpace) = CHAR_NULL;
    823 
    824     // finally, set up to return
    825 
    826     fullRequestPLS = fullRequestBuffer;
    827 
    828     return true;
    829 }
    830 
    831 OSCL_EXPORT_REF void
    832 RTSPOutgoingMessage::bind(const RTSPIncomingMessage & incoming)
    833 {
    834 
    835     StrCSumPtrLen timeStampName("Timestamp");
    836 
    837 
    838     cseqIsSet = incoming.cseqIsSet;
    839     cseq = incoming.cseq;
    840 
    841     sessionIdIsSet = incoming.sessionIdIsSet;
    842     sessionId = incoming.sessionId;
    843 
    844     const StrPtrLen * timeStampVal;
    845     if (NULL != (timeStampVal = incoming.queryField(timeStampName)))
    846     {
    847         addField(&timeStampName, timeStampVal);
    848     }
    849 }
    850 
    851 void
    852 RTSPOutgoingMessage::composeTransport(char* trans, RtspTransport* rtspTrans)
    853 {
    854     const int tmp_size = 64;
    855     char tmp[tmp_size];
    856     if (rtspTrans->protocolIsSet)
    857     {
    858         if (rtspTrans->protocol == RtspTransport::RTP_PROTOCOL)
    859         {
    860             oscl_strcat(trans, "RTP");
    861         }
    862         else if (rtspTrans->protocol == RtspTransport::RDT_PROTOCOL)
    863         {
    864             oscl_strcat(trans, "x-pn-tng");
    865         }
    866     }
    867     if (rtspTrans->profileIsSet)
    868     {
    869         if (rtspTrans->profile == RtspTransport::AVP_PROFILE)
    870         {
    871             oscl_strcat(trans, "/AVP");
    872         }
    873         else if (rtspTrans->profile == RtspTransport::TCP_PROFILE)
    874         {//Real
    875             oscl_strcat(trans, "/tcp");
    876         }
    877     }
    878     if (rtspTrans->transportTypeIsSet)
    879     {
    880         if (rtspTrans->transportType == RtspTransport::UDP_TRANSPORT)
    881         {
    882             oscl_strcat(trans, "/UDP");
    883         }
    884         else if (rtspTrans->transportType == RtspTransport::TCP_TRANSPORT)
    885         {
    886             oscl_strcat(trans, "/TCP");
    887         }
    888     }
    889     if (rtspTrans->deliveryIsSet)
    890     {
    891         if (rtspTrans->delivery == RtspTransport::UNICAST_DELIVERY)
    892         {
    893             oscl_strcat(trans, ";unicast");
    894         }
    895         if (rtspTrans->delivery == RtspTransport::MULTICAST_DELIVERY)
    896         {
    897             oscl_strcat(trans, ";multicast");
    898         }
    899     }
    900 
    901     if (rtspTrans->destinationIsSet)
    902     {
    903         if (rtspTrans->destination.c_str() && rtspTrans->destination.length())
    904         {
    905             oscl_strcat(trans, rtspTrans->destination.c_str());
    906         }
    907     }
    908 
    909     if (rtspTrans->channelIsSet)
    910     {
    911         oscl_snprintf(tmp, 63, ";interleaved=%d-%d", rtspTrans->channel1,
    912                       rtspTrans->channel2);
    913         oscl_strcat(trans, tmp);
    914     }
    915 
    916     if (rtspTrans->client_portIsSet)
    917 #ifdef ASF_STREAMING
    918         if (rtspTrans->client_port2 == NULL)
    919         {
    920             oscl_snprintf(tmp, 63, ";client_port=%d", rtspTrans->client_port1);
    921             oscl_strcat(trans, tmp);
    922         }
    923         else
    924 #endif
    925         {
    926             oscl_snprintf(tmp, 63, ";client_port=%d-%d", rtspTrans->client_port1, rtspTrans->client_port2);
    927             oscl_strcat(trans, tmp);
    928         }
    929     if (rtspTrans->server_portIsSet)
    930     {
    931         oscl_snprintf(tmp, 63, ";server_port=%d-%d", rtspTrans->server_port1, rtspTrans->server_port2);
    932         oscl_strcat(trans, tmp);
    933     }
    934     if (rtspTrans->modeIsSet)
    935     {
    936         if (rtspTrans->mode.play_mode)
    937         {
    938             oscl_strncpy(tmp, ";mode=play", 9);
    939             tmp[9] = NULL_TERM_CHAR;
    940             oscl_strcat(trans, tmp);
    941         }
    942         if (rtspTrans->mode.record_mode)
    943         {
    944             oscl_strncpy(tmp, ";mode=record", 11);
    945             tmp[11] = NULL_TERM_CHAR;
    946             oscl_strcat(trans, tmp);
    947             if (rtspTrans->append)
    948             {
    949                 oscl_strncpy(tmp, ";append", 6);
    950                 tmp[6] = NULL_TERM_CHAR;
    951                 oscl_strcat(trans, tmp);
    952             }
    953         }
    954     }
    955     if (rtspTrans->ttlIsSet)
    956     {
    957         oscl_snprintf(tmp, 63, ";ttl=%d", rtspTrans->ttl);
    958         oscl_strcat(trans, tmp);
    959     }
    960     if (rtspTrans->layersIsSet)
    961     {
    962         oscl_snprintf(tmp, 63, ";layers=%u", rtspTrans->layers);
    963         oscl_strcat(trans, tmp);
    964     }
    965     if (rtspTrans->ssrcIsSet)
    966     {
    967         oscl_snprintf(tmp, 63, ";ssrc=%.8x", rtspTrans->ssrc);
    968         oscl_strcat(trans, tmp);
    969     }
    970 
    971 
    972 }
    973 
    974 
    975