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