• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
reset()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 *
retrieveComposedBuffer()37 RTSPOutgoingMessage::retrieveComposedBuffer()
38 {
39     return &fullRequestPLS;
40 }
41 
42 OSCL_EXPORT_REF bool
addField(StrCSumPtrLen * newFieldName,const StrPtrLen * newFieldValue)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
addField(StrCSumPtrLen * newFieldName,const char * newValue)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
compose()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
bind(const RTSPIncomingMessage & incoming)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
composeTransport(char * trans,RtspTransport * rtspTrans)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