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