dvrengine/CommonRecordingEngine/src/CCRRTSPCommand.cpp
branchRCL_3
changeset 47 826cea16efd9
parent 45 798ee5f1972c
child 48 13a33d82ad98
equal deleted inserted replaced
45:798ee5f1972c 47:826cea16efd9
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    RTSP command parser and producer*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CCRRtspCommand.h"
       
    22 #include "CCRSock.h"
       
    23 #include <imcvcodc.h>
       
    24 #include <Hash.h>
       
    25 #include "videoserviceutilsLogger.h"
       
    26 
       
    27 // CONSTANTS
       
    28 const TReal KRealZero( 0.0 ); 
       
    29 const TReal KRealMinusOne( -1.0 ); 
       
    30 // Length of a digest hash before converting to hex.
       
    31 const TInt KCRRawHashLength( 16 );
       
    32 // Length of a digest hash when represented in hex
       
    33 const TInt KCRHashLength( 32 );
       
    34 
       
    35 // ============================ MEMBER FUNCTIONS ===============================
       
    36 
       
    37 // -----------------------------------------------------------------------------
       
    38 // CCRRtspCommand::NewL
       
    39 // Two-phased constructor.
       
    40 // -----------------------------------------------------------------------------
       
    41 //
       
    42 CCRRtspCommand* CCRRtspCommand::NewL()
       
    43     {
       
    44     CCRRtspCommand* self = new( ELeave ) CCRRtspCommand();
       
    45     CleanupStack::PushL( self );
       
    46     self->ConstructL();
       
    47     CleanupStack::Pop( self );
       
    48     return self;
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CCRRtspCommand::CCRRtspCommand
       
    53 // C++ default constructor can NOT contain any code, that might leave.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CCRRtspCommand::CCRRtspCommand()
       
    57   : iCommand( ERTSPCommandNOCOMMAND )
       
    58     {  
       
    59     // None
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CCRRtspCommand::ConstructL
       
    64 // Symbian 2nd phase constructor can leave.
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 void CCRRtspCommand::ConstructL()
       
    68     {
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CCRRtspCommand::~CCRRtspCommand
       
    73 // Destructor.
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 CCRRtspCommand::~CCRRtspCommand()
       
    77     {
       
    78     LOG( "CCRRtspCommand::~CCRRtspCommand" );
       
    79     
       
    80     // iRtspText is deleted in base class destructor
       
    81     delete iAuthHeader;
       
    82     delete iMD5Calculator;
       
    83     delete iUserAgent;
       
    84     delete iWapProfile;
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CCRRtspCommand::TryParseL
       
    89 // 
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 void CCRRtspCommand::TryParseL( const TDesC8 &aString ) 
       
    93     {
       
    94     // try to find out if end of the command has been received
       
    95     // "RTSP/1.0 XXX\r\n\r\n" at least..
       
    96     const TInt KDVRMinCommandLen( 14 ); 
       
    97     TInt replyEndOffSet( ( aString.Length() < KDVRMinCommandLen )?
       
    98                            KDVRMinCommandLen: aString.Find( KCR2NewLines() ) ); 
       
    99     if ( replyEndOffSet == KErrNotFound )
       
   100         {
       
   101         // need to have more, do nothing yet
       
   102         LOG( "CCRRtspCommand::TryParseL() out because response not complete" );
       
   103         User::Leave( KErrUnderflow ); 
       
   104         }
       
   105 
       
   106     // copy the stuff into local variable:      
       
   107     delete iRtspText; iRtspText = NULL; 
       
   108     iRtspText = aString.AllocL(); 
       
   109     iCommand = ERTSPCommandNOCOMMAND;
       
   110 
       
   111     // try each command in order: 
       
   112     if ( iRtspText->Find( KCROPTIONS() ) == 0 )
       
   113         {
       
   114         // it was OPTIONS command
       
   115         LOG( "CCRRtspCommand::TryParseL() -> OPTIONS" );
       
   116         iCommand = ERTSPCommandOPTIONS;
       
   117         }
       
   118     else if ( iRtspText->Find( KCRDESCRIBE() ) == 0 )
       
   119         {
       
   120         LOG( "CCRRtspCommand::TryParseL() -> DESCRIBE" );
       
   121         iCommand = ERTSPCommandDESCRIBE;
       
   122         }  
       
   123     else if ( iRtspText->Find( KCRTEARDOWN() ) == 0 )
       
   124         {
       
   125         LOG( "CCRRtspCommand::TryParseL() -> TEARDOWN" );
       
   126         iCommand = ERTSPCommandTEARDOWN;        
       
   127         }                   
       
   128     else if ( iRtspText->Find( KCRPAUSE() ) == 0 )
       
   129         {
       
   130         LOG( "CCRRtspCommand::TryParseL() -> PAUSE" );
       
   131         iCommand = ERTSPCommandPAUSE;       
       
   132         }                                       
       
   133     else if ( iRtspText->Find( KCRSETUP() ) == 0 )
       
   134         {
       
   135         LOG( "CCRRtspCommand::TryParseL() -> SETUP" );
       
   136         iCommand = ERTSPCommandSETUP;       
       
   137         }
       
   138     else if ( iRtspText->Find( KCRPLAY() ) == 0 )
       
   139         {
       
   140         LOG( "CCRRtspCommand::TryParseL() -> PLAY" );
       
   141         iCommand = ERTSPCommandPLAY;        
       
   142         }  
       
   143     else
       
   144         {
       
   145         User::Leave( KErrNotSupported ); 
       
   146         }
       
   147 
       
   148     // then find CSeq
       
   149     FindCSeqL();    
       
   150     // then find session id
       
   151     FindSessionIdL(); 
       
   152     // then find possible content. for commands it is usually not there
       
   153     FindContentL(); 
       
   154     // find URL
       
   155     FindURLL(); 
       
   156     // find possible transport method
       
   157     // IMPORTANT: should be done before parsing client port
       
   158     FindTransport();
       
   159     // find possible client port
       
   160     FindClientPorts();
       
   161     // find possible range-header
       
   162     ParseRange();
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CCRRtspCommand::FindURLL
       
   167 // in rtsp the URL is between first and second whitespace.
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 void CCRRtspCommand::FindURLL( void ) 
       
   171     {
       
   172 #ifdef _DEBUG   
       
   173     _LIT( KPanicStr, "RTSPCommon" ); 
       
   174     __ASSERT_DEBUG( iRtspText, 
       
   175                     User::Panic( KPanicStr, KErrBadHandle ) );
       
   176 #endif                    
       
   177     
       
   178     iURL.Set( NULL, 0 );
       
   179     TInt spaceOffset( iRtspText->Locate( ' ' ) ); 
       
   180     if ( spaceOffset < 0 ) 
       
   181         {
       
   182         User::Leave( KErrNotSupported ); 
       
   183         }
       
   184         
       
   185     TPtrC8 beginningFromUrl( iRtspText->Right( iRtspText->Length() - 
       
   186                                              ( spaceOffset + 1 ) ) ) ;      
       
   187     spaceOffset = beginningFromUrl.Locate( ' ' ); 
       
   188     if ( spaceOffset < 0 ) 
       
   189         {
       
   190         User::Leave( KErrNotSupported ); 
       
   191         }
       
   192     
       
   193     iURL.Set( beginningFromUrl.Left( spaceOffset ) ); 
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CCRRtspCommand::URL
       
   198 //
       
   199 // method that returns URL
       
   200 // -----------------------------------------------------------------------------
       
   201 //  
       
   202 TInt CCRRtspCommand::URL( TPtrC8& aURL ) 
       
   203     {
       
   204     if ( iURL.Ptr() != NULL )   
       
   205         {
       
   206         aURL.Set ( iURL ); 
       
   207         return KErrNone;
       
   208         }
       
   209 
       
   210     return KErrNotFound; 
       
   211     }
       
   212 
       
   213 // -----------------------------------------------------------------------------
       
   214 // CCRRtspCommand::SetURL
       
   215 //
       
   216 // -----------------------------------------------------------------------------
       
   217 //  
       
   218 void CCRRtspCommand::SetURL ( const TDesC8& aURL ) 
       
   219     {
       
   220     iURL.Set ( aURL ); 
       
   221     }
       
   222     
       
   223 // -----------------------------------------------------------------------------
       
   224 // CCRRtspCommand::SetAuthentication
       
   225 //
       
   226 // -----------------------------------------------------------------------------
       
   227 //  
       
   228 void CCRRtspCommand::SetAuthentication( TBool aAuth ) 
       
   229     {
       
   230     iAuthenticationNeeded = aAuth;
       
   231     }
       
   232 
       
   233 // -----------------------------------------------------------------------------
       
   234 // CCRRtspCommand::SetUserAgentL
       
   235 //
       
   236 // -----------------------------------------------------------------------------
       
   237 //  
       
   238 void CCRRtspCommand::SetUserAgentL( const TDesC8& aUserAgent )
       
   239     {
       
   240     delete iUserAgent; iUserAgent = NULL;
       
   241     iUserAgent = aUserAgent.AllocL();
       
   242     }
       
   243 
       
   244 // -----------------------------------------------------------------------------
       
   245 // CCRRtspCommand::SetBandwidth
       
   246 //
       
   247 // -----------------------------------------------------------------------------
       
   248 //  
       
   249 void CCRRtspCommand::SetBandwidth( TInt aBandwidth )
       
   250     {
       
   251     iBandwidth = aBandwidth;
       
   252     iBandwidthAvailable = ETrue;
       
   253     }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // CCRRtspCommand::SetWapProfileL
       
   257 //
       
   258 // -----------------------------------------------------------------------------
       
   259 //  
       
   260 void CCRRtspCommand::SetWapProfileL( const TDesC8& aWapProfile )
       
   261     {
       
   262     delete iWapProfile; iWapProfile = NULL;
       
   263     iWapProfile = aWapProfile.AllocL();
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CCRRtspCommand::SetCommand
       
   268 //
       
   269 // -----------------------------------------------------------------------------
       
   270 //  
       
   271 void CCRRtspCommand::SetCommand( TCommand aCommand ) 
       
   272     {
       
   273     iCommand = aCommand; 
       
   274     }
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CCRRtspCommand::Command
       
   278 //
       
   279 // -----------------------------------------------------------------------------
       
   280 //  
       
   281 CCRRtspCommand::TCommand CCRRtspCommand::Command( void ) const 
       
   282     {
       
   283     return iCommand;    
       
   284     }       
       
   285             
       
   286 // -----------------------------------------------------------------------------
       
   287 // CCRRtspCommand::ProduceL
       
   288 //
       
   289 // -----------------------------------------------------------------------------
       
   290 //  
       
   291 TPtrC8& CCRRtspCommand::ProduceL( void ) 
       
   292     {
       
   293     // First common part for all commands, except actual command
       
   294     delete iRtspText; iRtspText = NULL;
       
   295     iRtspText = HBufC8::NewL( KMaxName );
       
   296     iRtspText->Des().Zero();
       
   297     
       
   298     switch ( iCommand )
       
   299         {
       
   300         case ERTSPCommandOPTIONS:
       
   301             AppendL( iRtspText, KCROPTIONS ); 
       
   302             break;
       
   303         
       
   304         case ERTSPCommandDESCRIBE:
       
   305             AppendL( iRtspText, KCRDESCRIBE ); 
       
   306             break;
       
   307         
       
   308         case ERTSPCommandTEARDOWN:     
       
   309             AppendL( iRtspText, KCRTEARDOWN ); 
       
   310             break;
       
   311         
       
   312         case ERTSPCommandPAUSE:
       
   313             AppendL( iRtspText, KCRPAUSE ); 
       
   314             break;
       
   315         
       
   316         case ERTSPCommandSETUP:        
       
   317             AppendL( iRtspText, KCRSETUP ); 
       
   318             break;
       
   319         
       
   320         case ERTSPCommandPLAY : 
       
   321             AppendL( iRtspText, KCRPLAY ); 
       
   322             break;
       
   323         
       
   324         default:
       
   325             User::Leave( KErrNotSupported ); 
       
   326             break;
       
   327         }
       
   328     
       
   329     AppendL( iRtspText, iURL ); 
       
   330     AppendL( iRtspText, KCRSpace ); 
       
   331     AppendL( iRtspText, KCRRTSP10 ); 
       
   332     AppendL( iRtspText, KCRNewLine ); 
       
   333     AppendL( iRtspText, KCRCSeq ); 
       
   334     AppendNumL( iRtspText, iCSeq );
       
   335     AppendL( iRtspText, KCRNewLine );
       
   336 
       
   337     if ( iUserAgent )
       
   338         {
       
   339         TPtrC8 useragent( iUserAgent->Des() );
       
   340         AppendFormatL( iRtspText, KCRRTSPUserAgentHeader, &useragent );
       
   341         }
       
   342 
       
   343     // then variable tail depending on command
       
   344     switch ( iCommand )
       
   345         {
       
   346         case ERTSPCommandOPTIONS:
       
   347             if ( iSessionId.Ptr() != NULL ) 
       
   348                 {
       
   349                 AppendL( iRtspText, KCRSessionStr() ); 
       
   350                 AppendL( iRtspText, iSessionId ); // now only session number
       
   351                 AppendL( iRtspText, KCRNewLine );                
       
   352                 }
       
   353             break;
       
   354         
       
   355         case ERTSPCommandDESCRIBE:
       
   356             {
       
   357             AppendL( iRtspText, KCRAcceptSDP );
       
   358             if ( iWapProfile )
       
   359                 {
       
   360                 TPtrC8 profile = iWapProfile->Des();
       
   361                 AppendFormatL( iRtspText, KCRRTSPXWapProfile, &profile );
       
   362                 }
       
   363             if ( iBandwidthAvailable )
       
   364                 {
       
   365                 AppendFormatL( iRtspText, KCRRTSPBandwidth, iBandwidth );
       
   366                 }
       
   367             }
       
   368             break;
       
   369         
       
   370         case ERTSPCommandTEARDOWN:     
       
   371             if ( iSessionId.Ptr() != NULL ) 
       
   372                 {
       
   373                 AppendL( iRtspText, KCRSessionStr() ); 
       
   374                 AppendL( iRtspText, iSessionId ); // now only session number
       
   375                 AppendL( iRtspText, KCRNewLine );                
       
   376                 }
       
   377             break;
       
   378 
       
   379         case ERTSPCommandPAUSE:        
       
   380             if ( iSessionId.Ptr() != NULL ) 
       
   381                 {
       
   382                 AppendL( iRtspText, KCRSessionStr() ); 
       
   383                 AppendL( iRtspText, iSessionId ); // now only session number
       
   384                 AppendL( iRtspText, KCRNewLine );                
       
   385                 }
       
   386             break;
       
   387 
       
   388         case ERTSPCommandSETUP:        
       
   389             {
       
   390             // build transport header according to chosen method
       
   391             switch ( iTransport )
       
   392                 {
       
   393                 case ERTPOverUDP:
       
   394                     AppendFormatL( iRtspText, KCRTransportHeaderUDP,
       
   395                                    iClientPort, iClientPort + 1 );
       
   396                     break;
       
   397                 case ERTPOverTCP:
       
   398                     AppendFormatL( iRtspText, KCRTransportHeaderTCP,
       
   399                                    iClientPort, iClientPort + 1 );
       
   400                     break;
       
   401                 
       
   402                 case ERTPOverMulticast:
       
   403                     AppendL( iRtspText, KCRTransportHeaderMulticast );
       
   404                     break;
       
   405                 }
       
   406 
       
   407             // Session: 5273458854096827704         
       
   408             if ( iSessionId.Ptr() != NULL ) 
       
   409                 {
       
   410                 AppendL( iRtspText, KCRSessionStr ); 
       
   411                 AppendL( iRtspText, iSessionId ); // now only session number
       
   412                 AppendL( iRtspText, KCRNewLine ); 
       
   413                 }
       
   414             if ( iWapProfile )
       
   415                 {
       
   416                 TPtrC8 profile( iWapProfile->Des() );
       
   417                 AppendFormatL( iRtspText, KCRRTSPXWapProfile, &profile );
       
   418                 }
       
   419             }
       
   420             break;
       
   421             
       
   422         case ERTSPCommandPLAY: 
       
   423             {
       
   424             if ( !( iLowerRange == KRealZero && iUpperRange == KRealMinusOne ) )
       
   425                 {
       
   426                 // Range was something else than 0,-1
       
   427                 TBuf8<KMaxName> buf( KCRRangeHeader );
       
   428                 TRealFormat format( 10, 3 ); 
       
   429                 format.iTriLen = 0; 
       
   430                 format.iPoint = '.';
       
   431                 buf.AppendNum( iLowerRange, format );
       
   432                 buf.Append( '-' ); 
       
   433                 if ( iUpperRange > KRealZero )
       
   434                     {
       
   435                     buf.AppendNum( iUpperRange, format );
       
   436                     }
       
   437                 
       
   438                 buf.Append( KCRNewLine );
       
   439                 AppendL( iRtspText, buf );
       
   440                 }
       
   441             if ( iSessionId.Ptr() != NULL ) 
       
   442                 {
       
   443                 AppendL( iRtspText, KCRSessionStr() ); 
       
   444                 AppendL( iRtspText, iSessionId ); // now only session number
       
   445                 AppendL( iRtspText, KCRNewLine ); 
       
   446                 }
       
   447             }
       
   448             break;
       
   449 
       
   450         default:
       
   451             User::Leave( KErrNotSupported ); 
       
   452             break;
       
   453         }           
       
   454     
       
   455     if ( iAuthenticationNeeded )
       
   456         {
       
   457         TBool useDigest( EFalse );
       
   458         
       
   459         if ( iAuthType && ( iAuthType->FindC( KCRAuthDigest ) != KErrNotFound ) )
       
   460             {
       
   461             useDigest = ETrue;
       
   462             }
       
   463         
       
   464         switch ( iCommand )
       
   465             {
       
   466             case ERTSPCommandOPTIONS :
       
   467                 useDigest ? CalculateDigestResponseL( KCROPTIONSNoSpace ) :
       
   468                             CalculateBasicResponseL( KCROPTIONSNoSpace );
       
   469                 
       
   470                 if ( iAuthHeader ) 
       
   471                     {
       
   472                     AppendL( iRtspText, iAuthHeader->Des() );
       
   473                     }
       
   474                 break;
       
   475             
       
   476             case ERTSPCommandDESCRIBE :
       
   477                 useDigest ? CalculateDigestResponseL( KCRDESCRIBENoSpace ) :
       
   478                             CalculateBasicResponseL( KCRDESCRIBENoSpace );  
       
   479                
       
   480                 if ( iAuthHeader ) 
       
   481                     {
       
   482                     AppendL( iRtspText, iAuthHeader->Des() );
       
   483                     }
       
   484                 break;
       
   485             
       
   486             case ERTSPCommandTEARDOWN :     
       
   487                 useDigest ? CalculateDigestResponseL( KCRTEARDOWNNoSpace ) :
       
   488                             CalculateBasicResponseL( KCRTEARDOWNNoSpace );
       
   489                 
       
   490                 if ( iAuthHeader ) 
       
   491                     {               
       
   492                     AppendL( iRtspText, iAuthHeader->Des() );
       
   493                     }
       
   494                 break;
       
   495             
       
   496             case ERTSPCommandPAUSE :        
       
   497                 useDigest ? CalculateDigestResponseL( KCRPAUSENoSpace ) :
       
   498                             CalculateBasicResponseL( KCRPAUSENoSpace );
       
   499                 
       
   500                 if ( iAuthHeader ) 
       
   501                     {           
       
   502                     AppendL( iRtspText, iAuthHeader->Des() );
       
   503                     }
       
   504                 break;
       
   505             
       
   506             case ERTSPCommandSETUP :        
       
   507                 useDigest ? CalculateDigestResponseL( KCRSETUPNoSpace ) :
       
   508                             CalculateBasicResponseL( KCRSETUPNoSpace );
       
   509                 
       
   510                 if ( iAuthHeader ) 
       
   511                     {
       
   512                     AppendL( iRtspText, iAuthHeader->Des() );
       
   513                     }
       
   514                 break;
       
   515             
       
   516             case ERTSPCommandPLAY :  
       
   517                 useDigest ? CalculateDigestResponseL( KCRPLAYNoSpace ) :
       
   518                             CalculateBasicResponseL( KCRPLAYNoSpace );
       
   519                 
       
   520                 if ( iAuthHeader ) 
       
   521                     {           
       
   522                     AppendL( iRtspText, iAuthHeader->Des() );
       
   523                     }
       
   524                 break;
       
   525             
       
   526             default:
       
   527                 User::Leave( KErrNotSupported ); 
       
   528                 break;
       
   529             }       
       
   530         }
       
   531         
       
   532     AppendL( iRtspText, KCRNewLine ); 
       
   533     iProductDescriptor.Set( *iRtspText );
       
   534     return iProductDescriptor;
       
   535     }   
       
   536     
       
   537 // -----------------------------------------------------------------------------
       
   538 // CCRRtspCommand::AppendL
       
   539 //
       
   540 // -----------------------------------------------------------------------------
       
   541 //      
       
   542 void CCRRtspCommand::AppendL( HBufC8*& aBuffer, const TDesC8& aStr )
       
   543     {
       
   544     TPtr8 ptr( aBuffer->Des() );
       
   545     if ( ( ptr.Length() + aStr.Length() ) >= ptr.MaxLength() )
       
   546         {
       
   547         const TInt newLength( ptr.Length() + aStr.Length() + KMaxName );
       
   548         aBuffer = aBuffer->ReAllocL( newLength );
       
   549         ptr.Set( aBuffer->Des() );
       
   550         }
       
   551     
       
   552     ptr.Append( aStr );
       
   553     }
       
   554     
       
   555 // -----------------------------------------------------------------------------
       
   556 // CCRRtspCommand::AppendNumL
       
   557 //
       
   558 // -----------------------------------------------------------------------------
       
   559 //      
       
   560 void CCRRtspCommand::AppendNumL( HBufC8*& aBuffer, const TInt aNum )
       
   561     {
       
   562     TPtr8 ptr( aBuffer->Des() );
       
   563     if ( ( ptr.Length() + KMaxInfoName ) >= ptr.MaxLength() )
       
   564         {
       
   565         const TInt newLength( ptr.Length() + KMaxInfoName + KMaxName );
       
   566         aBuffer = aBuffer->ReAllocL( newLength );
       
   567         ptr.Set( aBuffer->Des() );
       
   568         }
       
   569     
       
   570     ptr.AppendNum( aNum );
       
   571     }
       
   572     
       
   573 // -----------------------------------------------------------------------------
       
   574 // CCRRtspCommand::AppendFormatL
       
   575 //
       
   576 // -----------------------------------------------------------------------------
       
   577 //      
       
   578 void CCRRtspCommand::AppendFormatL(
       
   579     HBufC8*& aBuffer,
       
   580     TRefByValue<const TDesC8> aFmt, ... )
       
   581     {
       
   582     VA_LIST list;
       
   583     VA_START( list, aFmt );
       
   584     HBufC8* buf = HBufC8::NewLC( KMaxDataSize );
       
   585     buf->Des().FormatList( aFmt, list );
       
   586     VA_END( list );
       
   587 
       
   588     TPtr8 ptr( aBuffer->Des() );
       
   589     if ( ( ptr.Length() + buf->Length() ) >= ptr.MaxLength() )
       
   590         {
       
   591         const TInt newLength( ptr.Length() + buf->Length() + KMaxName );
       
   592         aBuffer = aBuffer->ReAllocL( newLength );
       
   593         ptr.Set( aBuffer->Des() );
       
   594         }
       
   595     
       
   596     ptr.Append( *buf );
       
   597     CleanupStack::PopAndDestroy( buf );
       
   598     }
       
   599     
       
   600 // -----------------------------------------------------------------------------
       
   601 // CCRRtspCommand::Hash
       
   602 // Calculates hash value ( from S60 HttpFilters )
       
   603 // -----------------------------------------------------------------------------
       
   604 //
       
   605 void CCRRtspCommand::HashL( const TDesC8& aMessage, TDes8& aHash )
       
   606     {
       
   607     LOG( "CCRRtspCommand::HashL() in" );
       
   608     // check if md5 calculator is already constructed
       
   609     if ( !iMD5Calculator )
       
   610         { 
       
   611         iMD5Calculator = CMD5::NewL();
       
   612         }
       
   613     // Calculate the 128 bit (16 byte) hash
       
   614     iMD5Calculator->Reset();
       
   615     TPtrC8 hash = iMD5Calculator->Hash( aMessage );
       
   616     
       
   617     // Now print it as a 32 byte hex number
       
   618     aHash.Zero();
       
   619     _LIT8( formatStr, "%02x" );
       
   620     TBuf8<2> scratch;
       
   621     for ( TInt i( 0 ); i < KCRRawHashLength; i++ )
       
   622         {
       
   623         scratch.Zero();
       
   624         scratch.Format( formatStr, hash[i] );
       
   625         aHash.Append( scratch );
       
   626         }
       
   627     
       
   628     LOG( "CCRRtspCommand::HashL() out" );
       
   629     }
       
   630 
       
   631 // -----------------------------------------------------------------------------
       
   632 // CCRRtspCommand::CalculateBasicResponseL
       
   633 //
       
   634 // -----------------------------------------------------------------------------
       
   635 //
       
   636 void CCRRtspCommand::CalculateBasicResponseL( const TDesC8& /*aMethod*/ )
       
   637     {
       
   638     LOG( "CCRRtspCommand::CalculateBasicResponseL() in" );
       
   639     
       
   640     if ( !( iUserName && iPassword  ) )
       
   641         {
       
   642         LOG( "CCRRtspCommand::CalculateBasicResponseL() out, username or password not set" );
       
   643         delete iAuthHeader; 
       
   644         iAuthHeader = NULL;
       
   645         return; // no can do
       
   646         }
       
   647     
       
   648     HBufC8* plainData = HBufC8::NewL( iUserName->Length() + 1 + // ':'
       
   649                                       iPassword->Length() );
       
   650     
       
   651     CleanupStack::PushL( plainData );
       
   652     
       
   653     plainData->Des().Append( *iUserName );
       
   654     plainData->Des().Append( ':' );
       
   655     plainData->Des().Append( *iPassword );
       
   656     
       
   657     // Max size = ((Bytes + 3 - (Bytes MOD 3)) /3) x 4 
       
   658     TInt base64MaxSize = ( ( plainData->Length() + 3 - 
       
   659             ( plainData->Length() % 3 ) ) / 3 ) * 4;
       
   660     
       
   661     HBufC8* encodedData = HBufC8::NewL( base64MaxSize );
       
   662     TPtr8 dataPrt( encodedData->Des() );   
       
   663     CleanupStack::PushL( encodedData );
       
   664     
       
   665     TImCodecB64 b64enc;
       
   666     b64enc.Initialise();
       
   667     b64enc.Encode( *plainData, dataPrt );
       
   668     
       
   669     delete iAuthHeader; 
       
   670     iAuthHeader = NULL;
       
   671     iAuthHeader = HBufC8::NewL( KCRAuthorizationBasicHeader().Length() + encodedData->Length() );           
       
   672     iAuthHeader->Des().Format( KCRAuthorizationBasicHeader, encodedData );
       
   673     
       
   674     CleanupStack::PopAndDestroy( encodedData );
       
   675     CleanupStack::PopAndDestroy( plainData );
       
   676     
       
   677     LOG( "CCRRtspCommand::CalculateBasicResponseL() out" );
       
   678     }
       
   679 
       
   680 // -----------------------------------------------------------------------------
       
   681 // CCRRtspCommand::CalculateDigestResponseL
       
   682 //
       
   683 // -----------------------------------------------------------------------------
       
   684 //
       
   685 void CCRRtspCommand::CalculateDigestResponseL( const TDesC8& aMethod )
       
   686     {
       
   687     LOG( "CCRRtspCommand::CalculateDigestResponseL() in" );
       
   688 
       
   689     if ( !( iUserName && iPassword && iNonce && iOpaque && iRealm && iUri ) )
       
   690         {
       
   691         LOG( "CCRRtspCommand::CalculateDigestResponseL() out, username or password not set" );
       
   692         delete iAuthHeader; iAuthHeader = NULL;
       
   693         return; // no can do
       
   694         }
       
   695 
       
   696     TBuf8<KCRHashLength> hash1;
       
   697     TBuf8<KCRHashLength> hash2;
       
   698     TBuf8<KCRHashLength> finalHash;
       
   699 
       
   700     // calculate the hash1 using "username:realm:password"
       
   701     HBufC8* hashPtr = HBufC8::NewL ( iUserName->Length() + 1 +  // ':'
       
   702                                      iRealm->Length() + 1 +      // ':' 
       
   703                                      iPassword->Length() );
       
   704     hashPtr->Des().Append( *iUserName );
       
   705     hashPtr->Des().Append( ':' );
       
   706     hashPtr->Des().Append( *iRealm );
       
   707     hashPtr->Des().Append( ':' );
       
   708     hashPtr->Des().Append( *iPassword );
       
   709     
       
   710     HashL( *hashPtr, hash1 );
       
   711     delete hashPtr; hashPtr = NULL;
       
   712 
       
   713     // calculate hash2 using "Method:uri"
       
   714     HBufC8* hashPtr2 = HBufC8::NewL(aMethod.Length() + 1 + iUri->Length() );
       
   715     hashPtr2->Des().Append( aMethod );
       
   716     hashPtr2->Des().Append( ':' );
       
   717     hashPtr2->Des().Append( *iUri );
       
   718     
       
   719     HashL( *hashPtr2, hash2 );
       
   720     delete hashPtr2; hashPtr2 = NULL;
       
   721 
       
   722     // calculate finalHash to be sent to remote server using
       
   723     // hash1 + ":" + nonce + ":" + hash2
       
   724     HBufC8* hashPtr3 = HBufC8::NewL( hash1.Length() + 1 + // ':'
       
   725                                      iNonce->Length() + 1 + // ':'
       
   726                                      hash2.Length() );
       
   727     hashPtr3->Des().Append( hash1 );
       
   728     hashPtr3->Des().Append( ':' );
       
   729     hashPtr3->Des().Append( *iNonce );
       
   730     hashPtr3->Des().Append( ':' );
       
   731     hashPtr3->Des().Append( hash2 );
       
   732 
       
   733     HashL( *hashPtr3, finalHash );
       
   734     delete hashPtr3; hashPtr3 = NULL;
       
   735 
       
   736     // generate the authentication header 
       
   737     if ( iOpaque->Length()  ) 
       
   738         {
       
   739         delete iAuthHeader; iAuthHeader = NULL;
       
   740         iAuthHeader = HBufC8::NewL( KCRAuthorizationHeader().Length() + 
       
   741             iUserName->Length() + iRealm->Length() + iNonce->Length() +
       
   742             iUri->Length() + finalHash.Length() + iOpaque->Length() );
       
   743         
       
   744         iAuthHeader->Des().Format( KCRAuthorizationHeader, iUserName,
       
   745             iRealm, iNonce, iUri, &finalHash, iOpaque );
       
   746         }
       
   747     else
       
   748         {
       
   749         delete iAuthHeader; iAuthHeader = NULL;
       
   750         iAuthHeader = HBufC8::NewL( KCRAuthorizationHeaderNoOpaque().Length() +
       
   751             iUserName->Length() + iRealm->Length() + iNonce->Length() +
       
   752             iUri->Length() + finalHash.Length() );
       
   753                                     
       
   754         iAuthHeader->Des().Format( KCRAuthorizationHeaderNoOpaque, iUserName,
       
   755             iRealm, iNonce, iUri, &finalHash );
       
   756         }
       
   757 
       
   758     LOG( "CCRRtspCommand::CalculateDigestResponseL() out" );   
       
   759     }
       
   760 
       
   761 //  End of File