dvrengine/CommonRecordingEngine/src/CCRRtspSink.cpp
branchRCL_3
changeset 23 13a33d82ad98
parent 0 822a42b6c3f1
equal deleted inserted replaced
22:826cea16efd9 23:13a33d82ad98
       
     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:    Class that instructs rtsp client about getting rtp*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CCRRtspSink.h"
       
    22 #include "CCRPacketBuffer.h"
       
    23 #include "CRRTSPCommon.h"
       
    24 #include "CCRConnection.h"
       
    25 #include "CCRStreamingSession.h"
       
    26 #include <ipvideo/CDvrSdpParser.h>
       
    27 #include <e32msgqueue.h>
       
    28 #include "videoserviceutilsLogger.h"
       
    29 
       
    30 // CONSTANTS
       
    31 const TInt KCCRRtspSinkDefaultServerPort( 20042 );
       
    32 
       
    33 _LIT( KCCRRtspSink, "Rtsp sink" );
       
    34 _LIT ( KCRLocalIPAddr, "127.0.0.1" );
       
    35 _LIT8( KBaseUrl, "rtsp://127.0.0.1/" ); 
       
    36 _LIT8( KVis0, "v=0\r\n" );
       
    37 _LIT8( KSdpOLine, "o=- 1 2 IN IP4 127.0.0.1\r\n" );
       
    38 _LIT8( KSdpSLine, "s=cre\r\n"); 
       
    39 _LIT8( KSdpCLine, "c=IN IP4 0.0.0.0\r\n"); 
       
    40 _LIT8( KSdpTLine, "t=0 0\r\n"); 
       
    41 _LIT8( KSdpBLine, "b=AS:"); 
       
    42 _LIT8( KSdpAudioMLine, "m=audio 0 RTP/AVP %d\r\n" );
       
    43 _LIT8( KSdpAudioAControlLine,
       
    44        "a=control:rtsp://127.0.0.1/default.3gp/AudioControlAddress\r\n" );
       
    45 _LIT8( KSdpvideoMLine, "m=video 0 RTP/AVP %d\r\n" );
       
    46 _LIT8( KSdpvideoAControlLine,
       
    47        "a=control:rtsp://127.0.0.1/default.3gp/VideoControlAddress\r\n" );
       
    48 _LIT8( KDescribeReply,
       
    49        "RTSP/1.0 200 OK\r\nCseq: %d\r\nContent-length: %d\r\n"
       
    50        "Content-Type: application/sdp\r\n\r\n%S" );
       
    51 _LIT8( KSetupReply, 
       
    52        "RTSP/1.0 200 OKr\nCseq: %dr\nSession: 42\r\n"
       
    53        "Transport: RTP/AVP;unicast;mode=play;client_port=%d-%d;"
       
    54        "server_port=%d-%d\r\n\r\n" );
       
    55 _LIT8( KControlAddr,"VideoControlAddress" );
       
    56 _LIT8( KPlayReply,
       
    57        "RTSP/1.0 200 OK\r\n" "Cseq: %d\r\n"
       
    58        "RTP-Info: url=rtsp://127.0.0.1/default.3gp/VideoControlAddress"
       
    59        ";seq=%u;rtptime=%u,url=rtsp://127.0.0.1/default.3gp/AudioControlAddress;"
       
    60        "seq=%u;rtptime=%u\r\n"
       
    61        "Session: 42\r\n" );
       
    62 _LIT8( KPlayReplyAudioOnly,
       
    63        "RTSP/1.0 200 OK\r\n" "Cseq: %d\r\n"
       
    64        "RTP-Info: url=rtsp://127.0.0.1/default.3gp/AudioControlAddress;"
       
    65        "seq=%u;rtptime=%u\r\n"
       
    66        "Session: 42\r\n" );
       
    67 _LIT8( KPlayReplyVideoOnly,
       
    68        "RTSP/1.0 200 OK\r\n" "Cseq: %d\r\n"
       
    69        "RTP-Info: url=rtsp://127.0.0.1/default.3gp/VideoControlAddress"
       
    70        ";seq=%u;rtptime=%u\r\n"
       
    71        "Session: 42\r\n" );
       
    72 
       
    73 _LIT8( KPauseReply, "RTSP/1.0 %d OK\r\nCseq: %d\r\nSession: 42\r\n\r\n" );
       
    74 _LIT8( KTearDownReply, "RTSP/1.0 200 OK\r\nCseq: %d\r\nSession: 42\r\n\r\n" );
       
    75 
       
    76 // ============================ MEMBER FUNCTIONS ===============================
       
    77 
       
    78 // -----------------------------------------------------------------------------
       
    79 // CCRRtspSink::NewL
       
    80 // Two-phased constructor.
       
    81 // -----------------------------------------------------------------------------
       
    82 //  
       
    83 CCRRtspSink* CCRRtspSink::NewL(
       
    84     CCRConnection& aConnection,
       
    85     RSocketServ& aSockServer,
       
    86     CCRStreamingSession::TCRSinkId aSinkId,
       
    87     const TInt& aLoopbackPort,
       
    88     CCRStreamingSession& aOwningSession )
       
    89     {
       
    90     CCRRtspSink* self = new( ELeave ) 
       
    91         CCRRtspSink( aConnection, aSockServer, aSinkId, aOwningSession );
       
    92     CleanupStack::PushL( self );
       
    93     self->ConstructL( aLoopbackPort );
       
    94     CleanupStack::Pop( self );
       
    95     return self;
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // CCRRtspSink::CCRRtspSink
       
   100 // C++ default constructor can NOT contain any code, that might leave.
       
   101 // -----------------------------------------------------------------------------
       
   102 //  
       
   103 CCRRtspSink::CCRRtspSink(
       
   104     CCRConnection& aConnection,
       
   105     RSocketServ& aSockServer,
       
   106     CCRStreamingSession::TCRSinkId aSinkId,
       
   107     CCRStreamingSession& aOwningSession )
       
   108   : CCRPacketSinkBase( aOwningSession, aSinkId ), 
       
   109     iConnection( aConnection ),
       
   110     iSockServer( aSockServer ),
       
   111     iStage( ERTSPInit ),
       
   112     iSetupReceived( 0 ),
       
   113     iAudioSeq( KMaxTUint32 ),
       
   114     iAudioTS( KMaxTUint32 ),
       
   115     iVideoSeq( KMaxTUint32 ),
       
   116     iVideoTS( KMaxTUint32 ),
       
   117     iLowerRange( KRealZero ),
       
   118     iUpperRange( KRealMinusOne )
       
   119     {
       
   120     // None
       
   121     }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // CCRRtspSink::ConstructL
       
   125 // 2nd phase. 
       
   126 // -----------------------------------------------------------------------------
       
   127 //  
       
   128 void CCRRtspSink::ConstructL( const TInt& aLoopbackPort )
       
   129     {
       
   130     iReceivedData = HBufC8::NewL( 0 );
       
   131     iRopResponse = HBufC8::NewL( 0 );
       
   132     iSockArr[EROPControl] = CCRSock::NewL(
       
   133          *this, EROPControl, iConnection.Connection(), iSockServer, ETrue, ETrue );
       
   134     TInt err( iSockArr[EROPControl]->ListenPort( aLoopbackPort ) );
       
   135     LOG2( "CCRRtspSink::ConstructL(), aLoopbackPort: %d, err: %d", aLoopbackPort, err );      
       
   136     User::LeaveIfError( err );
       
   137     }
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CCRRtspSink::~CCRRtspSink
       
   141 // Destructor.
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 CCRRtspSink::~CCRRtspSink()
       
   145     {    
       
   146     LOG( "CCRRtspSink::~CCRRtspSink()" );
       
   147 
       
   148     for ( TInt i( 0 ); i < EROPMaxSockets; i++ )
       
   149         {
       
   150         delete iSockArr[i]; iSockArr[i] = NULL;
       
   151         }
       
   152     for ( TInt i( 0 ); i < CCRRtspCommand::ERTSPCommandNOCOMMAND; i++ )
       
   153         {
       
   154         delete iCommands[i]; iCommands[i] = NULL; 
       
   155         }       
       
   156         
       
   157     delete iSdpForRop; 
       
   158     delete iSdpParser;
       
   159     delete iRopResponse;
       
   160     delete iReceivedData; 
       
   161     }
       
   162     
       
   163 // -----------------------------------------------------------------------------
       
   164 // CCRRtspSink::ProduceSDPForRopL
       
   165 // 
       
   166 // -----------------------------------------------------------------------------
       
   167 //      
       
   168 void CCRRtspSink::ProduceSDPForRopL() 
       
   169     {
       
   170     if ( !iSdpParser )
       
   171         {
       
   172         User::Leave( KErrNotReady ); 
       
   173         }
       
   174     
       
   175     delete iSdpForRop; iSdpForRop = NULL;
       
   176     iSdpForRop = HBufC8::NewL( KMaxName );
       
   177         
       
   178     iSdpForRop->Des().Zero();
       
   179     AppendL( iSdpForRop, KVis0 ); 
       
   180     AppendL( iSdpForRop, KSdpOLine ); 
       
   181     AppendL( iSdpForRop, KSdpSLine ); 
       
   182     AppendL( iSdpForRop, KSdpCLine ); 
       
   183     AppendL( iSdpForRop, KSdpTLine );
       
   184     if ( ( iSdpParser->AudioBitrate() + iSdpParser->VideoBitrate() ) > 0 )
       
   185     	{
       
   186 	    AppendL( iSdpForRop, KSdpBLine ); 
       
   187     	AppendNumL( iSdpForRop, iSdpParser->AudioBitrate() +
       
   188     	                        iSdpParser->VideoBitrate() );
       
   189     	AppendL( iSdpForRop, KCRNewLine );
       
   190     	}
       
   191     
       
   192     RArray<TPtrC8> &sessionAttributes = iSdpParser->SessionAttributes();
       
   193     for ( TInt i( 0 ); i < sessionAttributes.Count(); i++ )
       
   194         {
       
   195         AppendL( iSdpForRop, sessionAttributes[i] );
       
   196         AppendL( iSdpForRop, KCRNewLine );
       
   197         }
       
   198     
       
   199     // Check whether audio exist.
       
   200     if ( iSdpParser->AudioControlAddr().Length() )
       
   201         { 
       
   202         AppendFormatL( iSdpForRop, KSdpAudioMLine, iSdpParser->MediaIdentifierAudio() );
       
   203         if ( iSdpParser->AudioBitrate() > 0 ) 
       
   204         	{
       
   205 	        AppendL( iSdpForRop, KSdpBLine ); 
       
   206     	    AppendNumL( iSdpForRop, iSdpParser->AudioBitrate() );
       
   207        	 	AppendL( iSdpForRop, KCRNewLine );
       
   208        	 	}
       
   209 
       
   210         AppendL( iSdpForRop, KSdpAudioAControlLine );
       
   211         
       
   212         RArray<TPtrC8> &audioAttributes = iSdpParser->AudioAttributes();
       
   213         for ( TInt i( 0 ); i < audioAttributes.Count(); i++ )
       
   214             {
       
   215             AppendL( iSdpForRop, audioAttributes[i] );
       
   216             AppendL( iSdpForRop, KCRNewLine );
       
   217             }
       
   218         }
       
   219 
       
   220     // Check whether Video exist.
       
   221     if ( iSdpParser->VideoControlAddr().Length() )
       
   222         {
       
   223         AppendFormatL( iSdpForRop, KSdpvideoMLine, iSdpParser->MediaIdentifierVideo() );
       
   224 		if ( iSdpParser->VideoBitrate() > 0 ) 
       
   225 			{             
       
   226         	AppendL( iSdpForRop, KSdpBLine ); 
       
   227         	AppendNumL( iSdpForRop, iSdpParser->VideoBitrate() );
       
   228         	AppendL( iSdpForRop, KCRNewLine );
       
   229         	}
       
   230         	
       
   231         AppendL( iSdpForRop, KSdpvideoAControlLine );
       
   232         
       
   233         RArray<TPtrC8> &videoAttributes = iSdpParser->VideoAttributes();
       
   234         for ( TInt i( 0 ); i < videoAttributes.Count(); i++ )
       
   235             {
       
   236             AppendL( iSdpForRop, videoAttributes[i] );
       
   237             AppendL( iSdpForRop, KCRNewLine );
       
   238             }
       
   239         }       
       
   240     }
       
   241         
       
   242 // -----------------------------------------------------------------------------
       
   243 // CCRRtspSink::SetSdpL
       
   244 // as a side-effect causes parsing of the sdp
       
   245 // -----------------------------------------------------------------------------
       
   246 //  
       
   247 void CCRRtspSink::SetSdpL( const TDesC8& aSdp )
       
   248     {
       
   249     LOG1( "CCRRtspSink::SetSdpL(), aSdp len: %d", aSdp.Length() );
       
   250     
       
   251     // Create SDP parser
       
   252     delete iSdpParser; iSdpParser = NULL;
       
   253     iSdpParser = CDvrSdpParser::NewL();
       
   254     iSdpParser->TryParseL( aSdp, KBaseUrl );
       
   255     ProduceSDPForRopL();
       
   256 
       
   257     if ( iStage == ERTSPDescSent )
       
   258         {
       
   259         ReplyToDescribeL();
       
   260         }
       
   261     }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // CCRRtspSink::NewPacketAvailable
       
   265 //
       
   266 // -----------------------------------------------------------------------------
       
   267 //      
       
   268 void CCRRtspSink::NewPacketAvailable()
       
   269     {
       
   270     if ( iBuffer )
       
   271         {
       
   272         // Stream of next packet
       
   273         MCRPacketSource::TCRPacketStreamId stream( 
       
   274             MCRPacketSource::EStreamIdCount );
       
   275         const TInt bookKeeping( iBuffer->GetStream( iSinkId, stream ) ); 
       
   276         
       
   277         // Packets in buffer.
       
   278         if ( stream != MCRPacketSource::EStreamIdCount )
       
   279             {
       
   280             TCRROPSockId socket( SocketFromStream( stream ) );
       
   281 
       
   282             // Is previous packet send ready.
       
   283 
       
   284             if ( iSockArr[socket] && !iSockArr[socket]->IsActive() )
       
   285                 {
       
   286                 // Get packet
       
   287                 TPtr8 packet( NULL, 0 );
       
   288                 iBuffer->GetPacket( bookKeeping, packet ); 
       
   289                 
       
   290                 // Now we have the packet, send it to rop:
       
   291                 iSockArr[socket]->SendData( packet ); 
       
   292 
       
   293     			if ( iStage == ERTSPPlaySent )
       
   294     				{
       
   295     				iStage = ERTSPPlaying;
       
   296     				}
       
   297 
       
   298                 }
       
   299             else
       
   300                 {
       
   301                 iPacketPendingInBuffer = ETrue; 
       
   302                 }
       
   303             }
       
   304         }
       
   305     }
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CCRRtspSink::SetSeqAndTS
       
   309 // 
       
   310 // -----------------------------------------------------------------------------
       
   311 //      
       
   312 void CCRRtspSink::SetSeqAndTS(
       
   313     TUint& aAudioSeq,
       
   314     TUint& aAudioTS,
       
   315     TUint& aVideoSeq,
       
   316     TUint& aVideoTS )
       
   317     {
       
   318     LOG1( "CRE ropsink SetSeqAndTS aseq=%u ", aAudioSeq );
       
   319     
       
   320     iAudioSeq = aAudioSeq;
       
   321     iAudioTS  = aAudioTS;
       
   322     iVideoSeq = aVideoSeq;
       
   323     iVideoTS  = aVideoTS;
       
   324     iSeqAndTSSet = ETrue; 
       
   325     
       
   326     if ( iStage == ERTSPReadyToPlay )
       
   327         {
       
   328         TRAPD( err,ReplyToPlayL() );
       
   329         if ( err != KErrNone ) 
       
   330             {
       
   331             LOG1( "CRE ropsink ReplyToPlayL L=%d", err );
       
   332             iOwningSession.SinkStops( Id() ); 
       
   333             }
       
   334         }   
       
   335     }
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CCRRtspSink::SetRange
       
   339 // 
       
   340 // -----------------------------------------------------------------------------
       
   341 //      
       
   342 void CCRRtspSink::SetRange( TReal aLower, TReal aUpper )
       
   343     {
       
   344     LOG2( "CRE CCRRtspSink SetRange (%f - %f)", aLower, aUpper );                     
       
   345     iLowerRange = aLower;
       
   346     iUpperRange = aUpper;
       
   347     }
       
   348     
       
   349 // -----------------------------------------------------------------------------
       
   350 // CCRRtspSink::StatusChanged
       
   351 // This is used currently for getting to know if we're in playing state or not
       
   352 // -----------------------------------------------------------------------------
       
   353 //      
       
   354 void CCRRtspSink::StatusChanged( MCRPacketSource::TCRPacketSourceState aNewState )
       
   355     {
       
   356     LOG2( "CCRRtspSink::StatusChanged(), iStage: %d, aNewState: %d", iStage, aNewState );    
       
   357     
       
   358     if ( aNewState == MCRPacketSource::ERtpStateSetupRepply )
       
   359         {
       
   360         if ( iStage == ERTSPDelayedSetup && iRopResponse->Length() > 0 )
       
   361             {
       
   362             SendControlData();
       
   363             }
       
   364 
       
   365         iSetupReceived++; // SETUP repply received
       
   366         }
       
   367     else if ( aNewState == MCRPacketSource::ERtpStatePlaying )
       
   368         {
       
   369         if ( iStage == ERTSPPlaySent || iStage == ERTSPReadyToPlay ) 
       
   370             {
       
   371             iStage = ERTSPPlaying;
       
   372             }
       
   373         }
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CCRRtspSink::DataReceived
       
   378 //
       
   379 // This is called when data is received from socket.
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 void CCRRtspSink::DataReceived( TInt aSockId, const TDesC8 &aData ) 
       
   383     {   
       
   384 #if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE ) 
       
   385     // Debug output follows
       
   386     if ( aSockId == EROPControl )
       
   387         {
       
   388         LOG2( "CCRRtspSink::DataReceived(), aSockId: %d, len: %d", 
       
   389                                             aSockId, aData.Length() );
       
   390         TName d( KNullDesC );
       
   391         for ( TInt i( 0 );  i < aData.Length(); i++ )
       
   392             {
       
   393             TChar c( aData[i] );
       
   394             d.Append( c ); 
       
   395             if ( ( i > 0 ) && ( i % 80 ) == 0 )
       
   396                 {
       
   397                 LOG1( ">%S<", &d );              
       
   398                 d.Zero(); 
       
   399                 }
       
   400             }
       
   401         
       
   402         LOG1( ">%S<", &d );
       
   403         }
       
   404 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
   405         
       
   406     switch ( aSockId )
       
   407         {
       
   408         case EROPControl: // RTSP is spoken in this sock
       
   409             {
       
   410             TRAPD( err, HandleReceivedEROPControlL( aData ) );
       
   411             if ( KErrNone != err )
       
   412                 {
       
   413                 LOG1( "ROPSink ProcessRtspCommandL leave %d", err );
       
   414                 iOwningSession.SinkStops( Id() ); 
       
   415                 }
       
   416             }
       
   417             break;
       
   418             
       
   419         case EROPVideoSend1:
       
   420         case EROPVideoSend2:
       
   421         case EROPAudioSend1:
       
   422         case EROPAudioSend2:
       
   423             {
       
   424             // Those packets that rop sends to us we do not need actions
       
   425             }
       
   426             break; 
       
   427         
       
   428         default:
       
   429             {
       
   430             LOG1( "default: Unknown aSockId: %d", aSockId );
       
   431             }
       
   432             break; 
       
   433         }
       
   434     }
       
   435 
       
   436 // -----------------------------------------------------------------------------
       
   437 // CCRRtspSink::HandleReceivedEROPControlL
       
   438 //
       
   439 // This is called after received data from EROPControl socket.
       
   440 // -----------------------------------------------------------------------------
       
   441 //
       
   442 void CCRRtspSink::HandleReceivedEROPControlL( const TDesC8& aData )
       
   443     {
       
   444     AppendL( iReceivedData, aData );
       
   445     ProcessRtspCommandL();
       
   446     }
       
   447 
       
   448 // -----------------------------------------------------------------------------
       
   449 // CCRRtspSink::SockStatusChange
       
   450 //
       
   451 // When socket status changes to something
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 void CCRRtspSink::SockStatusChange(
       
   455     TInt aSockId,
       
   456     CCRSock::TCRSockStatus aStatus,
       
   457     TInt aError )
       
   458     {
       
   459     if ( aStatus == CCRSock::EFailed )
       
   460         {
       
   461         LOG3( "CCRRtspSink::SockStatusChange, id: %d, failure: %d, aError: %d",
       
   462             aSockId, ( TInt )aStatus, aError );
       
   463         // here do DoCleanup()
       
   464         iOwningSession.SinkStops( Id() ); 
       
   465         }
       
   466 
       
   467 	if ( aSockId != EROPControl )
       
   468 		{
       
   469 	    // Delete used packet from buffer if the socket was udp packet socket
       
   470 	    iBuffer->HandleBufferSize();
       
   471 
       
   472 	    // Is there more packets to send.
       
   473 	    if ( iPacketPendingInBuffer )
       
   474 	        {
       
   475 	        NewPacketAvailable(); 
       
   476 	        iPacketPendingInBuffer =
       
   477 	            ( iBuffer->PacketsCount( iSinkId ) > KErrNotFound );
       
   478 	        }           
       
   479         }
       
   480      else
       
   481         {
       
   482         LOG3( "CCRRtspSink::SockStatusChange(), aSockId: %d, aStatus: %d, aError: %d",
       
   483             aSockId, ( TInt )aStatus, aError );
       
   484         }
       
   485 
       
   486 #if !defined LIVE_TV_FILE_TRACE && !defined LIVE_TV_RDEBUG_TRACE
       
   487     ( void )aError;
       
   488 #endif
       
   489     }
       
   490     
       
   491 // -----------------------------------------------------------------------------
       
   492 // CCRRtspSink::ProcessRtspCommandL
       
   493 //
       
   494 // Causes parsing of command
       
   495 // -----------------------------------------------------------------------------
       
   496 //
       
   497 void CCRRtspSink::ProcessRtspCommandL() 
       
   498     {
       
   499     LOG1( "CCRRtspSink::ProcessRtspCommandL(), iStage: %d", iStage );  
       
   500     
       
   501     CCRRtspCommand *command = CCRRtspCommand::NewL();
       
   502     CleanupStack::PushL( command );
       
   503     command->TryParseL( *iReceivedData ); 
       
   504     delete iCommands[command->Command()]; 
       
   505     iCommands[command->Command()] = command; 
       
   506     CleanupStack::Pop( command ); // it is now safely in instance variable
       
   507     ProduceRtspReplyL( command->Command() ); 
       
   508     iReceivedData->Des().Zero();
       
   509     }
       
   510     
       
   511 // -----------------------------------------------------------------------------
       
   512 // CCRRtspSink::ProduceRtspReplyL
       
   513 //
       
   514 // Causes sending of reply to rop
       
   515 // -----------------------------------------------------------------------------
       
   516 //
       
   517 void CCRRtspSink::ProduceRtspReplyL( CCRRtspCommand::TCommand aLastCommand )    
       
   518     {
       
   519     LOG2( "CCRRtspSink::ProduceRtspReplyL(), iStage: %d, aLastCommand: %d",
       
   520                                              iStage, aLastCommand ); 
       
   521     
       
   522     switch ( aLastCommand ) 
       
   523         {
       
   524         case CCRRtspCommand::ERTSPCommandOPTIONS:
       
   525             ReplyToOptionsL(); 
       
   526             break; 
       
   527         
       
   528         case CCRRtspCommand::ERTSPCommandDESCRIBE:
       
   529             if ( iSdpForRop ) 
       
   530                 {
       
   531                 ReplyToDescribeL();
       
   532                 }
       
   533             
       
   534             iStage = ERTSPDescSent;
       
   535             break;
       
   536         
       
   537         case CCRRtspCommand::ERTSPCommandSETUP:
       
   538             ReplyToSetupL();
       
   539             break; 
       
   540         
       
   541         case CCRRtspCommand::ERTSPCommandPLAY:
       
   542             if ( iSeqAndTSSet )
       
   543                 {
       
   544                 // we've either audio or video seq set, we can  proceed with play: 
       
   545                 ReplyToPlayL();
       
   546                 iStage = ERTSPPlaySent;
       
   547                 }
       
   548             else
       
   549                 {
       
   550                 TReal startPos( KRealZero ); 
       
   551                 TReal endPos( KRealZero );
       
   552                 iCommands[CCRRtspCommand::ERTSPCommandPLAY]->GetRange( startPos, endPos );
       
   553                 iOwningSession.PlayCommand( startPos, endPos );
       
   554                 iStage = ERTSPReadyToPlay;
       
   555                 }
       
   556             iSetupReceived = 0;
       
   557             break; 
       
   558         
       
   559         case CCRRtspCommand::ERTSPCommandPAUSE: 
       
   560             ReplyToPauseL( iStage != ERTSPPlaying ? KErrNotReady : iOwningSession.PauseCommand() );
       
   561             iSeqAndTSSet = EFalse;
       
   562             break;
       
   563         
       
   564         case CCRRtspCommand::ERTSPCommandTEARDOWN:
       
   565             iOwningSession.StopCommand();
       
   566             ReplyToTearDownL();
       
   567             break;
       
   568         
       
   569         default:
       
   570             // None
       
   571             break;
       
   572         }   
       
   573     }
       
   574 
       
   575 // -----------------------------------------------------------------------------
       
   576 // CCRRtspSink::ReplyToOptionsL
       
   577 //
       
   578 // Causes sending of reply to rop for options
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 void CCRRtspSink::ReplyToOptionsL()
       
   582     {
       
   583     LOG( "CCRRtspSink::ReplyToOptionsL()" );
       
   584 
       
   585     iRopResponse->Des().Zero();
       
   586     AppendFormatL( iRopResponse, KCROptionsReply, 
       
   587         iCommands[CCRRtspCommand::ERTSPCommandOPTIONS]->CSeq() );
       
   588     SendControlData();
       
   589     }
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 // CCRRtspSink::ReplyToDescribeL
       
   593 //
       
   594 // Causes sending of reply to rop for describe
       
   595 // -----------------------------------------------------------------------------
       
   596 //
       
   597 void CCRRtspSink::ReplyToDescribeL()
       
   598     {
       
   599     LOG( "CCRRtspSink::ReplyToDescribeL()" );
       
   600     
       
   601     User::LeaveIfNull( iSdpForRop );
       
   602     iRopResponse->Des().Zero();
       
   603     AppendFormatL( iRopResponse, KDescribeReply, 
       
   604         iCommands[CCRRtspCommand::ERTSPCommandDESCRIBE]->CSeq(),
       
   605         iSdpForRop->Des().Length(), &*iSdpForRop );
       
   606     SendControlData();
       
   607     }
       
   608 
       
   609 // -----------------------------------------------------------------------------
       
   610 // CCRRtspSink::ReplyToSetupL
       
   611 //
       
   612 // Causes sending of reply to rop for setup, either audio or video
       
   613 // -----------------------------------------------------------------------------
       
   614 //
       
   615 void CCRRtspSink::ReplyToSetupL()
       
   616     {
       
   617     LOG( "CCRRtspSink::ReplyToSetupL()" );
       
   618     if ( !iSdpParser )
       
   619         {
       
   620         User::Leave( KErrNotReady ); 
       
   621         }
       
   622     
       
   623     TPtrC8 url( NULL, 0 ); 
       
   624     iCommands[CCRRtspCommand::ERTSPCommandSETUP]->URL( url );
       
   625     if ( url.Find( KControlAddr) != KErrNotFound )
       
   626         { 
       
   627         // ROP is setting up video
       
   628         TInt videoPort(
       
   629             iCommands[CCRRtspCommand::ERTSPCommandSETUP]->ClientPort() );       
       
   630         LOG1( "CCRRtspSink::ReplyToSetupL  video port  %d", videoPort );
       
   631         iStage = ERTSPSetupVideoSent;
       
   632         
       
   633         // Setup sockets:           
       
   634         iSockArr[EROPVideoSend1] = CCRSock::NewL( *this, EROPVideoSend1,
       
   635             iConnection.Connection(), iSockServer, EFalse, ETrue );
       
   636         User::LeaveIfError( iSockArr[EROPVideoSend1]->ConnectSock(
       
   637             KCRLocalIPAddr, videoPort,
       
   638             KCCRRtspSinkDefaultServerPort ) );
       
   639 
       
   640         iSockArr[EROPVideoSend2] = CCRSock::NewL( *this, EROPVideoSend2,
       
   641             iConnection.Connection(), iSockServer, EFalse, ETrue );
       
   642         User::LeaveIfError( iSockArr[EROPVideoSend2]->ConnectSock(
       
   643             KCRLocalIPAddr, videoPort + 1,
       
   644             KCCRRtspSinkDefaultServerPort + 1 ) );
       
   645         }
       
   646     else
       
   647         { 
       
   648         // ROP is setting up audio
       
   649         TInt audioPort( 
       
   650             iCommands[CCRRtspCommand::ERTSPCommandSETUP]->ClientPort() );
       
   651         LOG1( "CCRRtspSink::ReplyToSetupL audio port: %d", audioPort );    
       
   652         iStage = ERTSPSetupAudioSent;      
       
   653         
       
   654         // Setup sockets:           
       
   655         iSockArr[EROPAudioSend1] = CCRSock::NewL( *this, EROPAudioSend1,
       
   656             iConnection.Connection(), iSockServer, EFalse, ETrue );
       
   657         User::LeaveIfError( iSockArr[EROPAudioSend1]->ConnectSock( 
       
   658             KCRLocalIPAddr, audioPort,
       
   659             KCCRRtspSinkDefaultServerPort + 2 ) );
       
   660         
       
   661         iSockArr[EROPAudioSend2] = CCRSock::NewL( *this, EROPAudioSend2,
       
   662             iConnection.Connection(), iSockServer, EFalse, ETrue );
       
   663         User::LeaveIfError( iSockArr[EROPAudioSend2]->ConnectSock( 
       
   664             KCRLocalIPAddr, audioPort + 1,
       
   665             KCCRRtspSinkDefaultServerPort + 3 ) );
       
   666         }
       
   667 
       
   668     iRopResponse->Des().Zero();
       
   669     AppendFormatL( iRopResponse, KSetupReply, 
       
   670         iCommands[CCRRtspCommand::ERTSPCommandSETUP]->CSeq(),
       
   671         iCommands[CCRRtspCommand::ERTSPCommandSETUP]->ClientPort(),
       
   672         iCommands[CCRRtspCommand::ERTSPCommandSETUP]->ClientPort() + 1,
       
   673         ( iStage == ERTSPSetupVideoSent )? KCCRRtspSinkDefaultServerPort:
       
   674                                            KCCRRtspSinkDefaultServerPort + 2,
       
   675         ( iStage == ERTSPSetupVideoSent )? KCCRRtspSinkDefaultServerPort + 1:
       
   676                                            KCCRRtspSinkDefaultServerPort + 3 ); 
       
   677     
       
   678     // If last setup, delay player response. Otherwise Helix will get prepare completed
       
   679     // and sends automatically PLAY command which ruins the state machine
       
   680     if ( iSetupReceived < 2 )
       
   681         {
       
   682         CDvrSdpParser::TDvrPacketProvidings content( iSdpParser->SupportedContent() );
       
   683         if ( iStage == ERTSPSetupVideoSent )
       
   684             {
       
   685             if ( ( iSetupReceived == 0 && content == CDvrSdpParser::EDvrVideoOnly ) ||
       
   686                  ( iSetupReceived <= 1 && content == CDvrSdpParser::EDvrBothAudioAndVideo ) )
       
   687                 {
       
   688                 iStage = ERTSPDelayedSetup;
       
   689                 LOG( "CCRRtspSink::ReplyToSetupL(), Video SETUP repply delayed.." );
       
   690                 }
       
   691             }
       
   692         else
       
   693             {
       
   694             if ( ( iSetupReceived == 0 && content == CDvrSdpParser::EDvrAudioOnly ) ||
       
   695                  ( iSetupReceived <= 1 && content == CDvrSdpParser::EDvrBothAudioAndVideo ) )
       
   696                 {
       
   697                 iStage = ERTSPDelayedSetup;
       
   698                 LOG( "CCRRtspSink::ReplyToSetupL(), Audio SETUP repply delayed.." );
       
   699                 }
       
   700             }
       
   701         }
       
   702 
       
   703     // Repply now or later
       
   704     if ( iStage != ERTSPDelayedSetup )
       
   705         {
       
   706         SendControlData();
       
   707         }
       
   708     }
       
   709 
       
   710 
       
   711 // -----------------------------------------------------------------------------
       
   712 // CCRRtspSink::ReplyToPlayL
       
   713 //
       
   714 // 
       
   715 // -----------------------------------------------------------------------------
       
   716 //
       
   717 void CCRRtspSink::ReplyToPlayL()
       
   718     {
       
   719     LOG( "CCRRtspSink::ReplyToPlayL()" );
       
   720 
       
   721     iRopResponse->Des().Zero();
       
   722     if ( iSdpParser->AudioControlAddr().Length() && 
       
   723          iSdpParser->VideoControlAddr().Length() )
       
   724         {
       
   725         AppendFormatL( iRopResponse, KPlayReply, 
       
   726             iCommands[CCRRtspCommand::ERTSPCommandPLAY]->CSeq(),
       
   727             iVideoSeq, iVideoTS, iAudioSeq, iAudioTS );
       
   728         } 
       
   729     else if ( iSdpParser->AudioControlAddr().Length() &&
       
   730              !iSdpParser->VideoControlAddr().Length() )
       
   731         {
       
   732         AppendFormatL( iRopResponse, KPlayReplyAudioOnly, 
       
   733             iCommands[CCRRtspCommand::ERTSPCommandPLAY]->CSeq(),
       
   734             iAudioSeq, iAudioTS );
       
   735         }
       
   736     else if ( !iSdpParser->AudioControlAddr().Length() && 
       
   737                iSdpParser->VideoControlAddr().Length() )
       
   738         {
       
   739         AppendFormatL( iRopResponse, KPlayReplyVideoOnly,
       
   740             iCommands[CCRRtspCommand::ERTSPCommandPLAY]->CSeq(),
       
   741             iVideoSeq, iVideoTS );
       
   742         } 
       
   743     else
       
   744         { // no audio, no video.
       
   745         iOwningSession.SinkStops( Id() ); 
       
   746         return; 
       
   747         }
       
   748         
       
   749     if ( !( iLowerRange == KRealZero && iUpperRange == KRealMinusOne ) ) 
       
   750         {
       
   751 		TBuf8<KMaxName> buf( KCRRangeHeader );
       
   752         TRealFormat format( 10, 3 );
       
   753         format.iTriLen = 0; 
       
   754         buf.AppendNum( iLowerRange, format );
       
   755         buf.Append( '-' ); 
       
   756         buf.AppendNum( iUpperRange, format );
       
   757         buf.Append( KCRNewLine );
       
   758         AppendFormatL( iRopResponse, buf );
       
   759         }
       
   760     
       
   761     AppendL( iRopResponse, KCRNewLine );
       
   762     SendControlData();
       
   763     }
       
   764 
       
   765 // -----------------------------------------------------------------------------
       
   766 // CCRRtspSink::ReplyToPlayL
       
   767 //
       
   768 // 
       
   769 // -----------------------------------------------------------------------------
       
   770 //
       
   771 void CCRRtspSink::ReplyToPauseL( TInt aErrorCode ) 
       
   772     {
       
   773     LOG1( "CCRRtspSink::ReplyToPauseL(), aErrorCode: %d", aErrorCode );
       
   774 
       
   775     iRopResponse->Des().Zero();
       
   776 
       
   777     switch ( aErrorCode )
       
   778         {
       
   779         case KErrNone:
       
   780             AppendFormatL( iRopResponse, KPauseReply,
       
   781                 CCRRtspResponse::ERTSPRespOK,  
       
   782                 iCommands[CCRRtspCommand::ERTSPCommandPAUSE]->CSeq() );
       
   783             iStage = ERTSPPauseSent;
       
   784             break; 
       
   785         
       
   786         case KErrNotReady:
       
   787             AppendFormatL( iRopResponse, KPauseReply,
       
   788                 CCRRtspResponse::ERTSPRespMethodNotValidInThisState,  
       
   789                 iCommands[CCRRtspCommand::ERTSPCommandPAUSE]->CSeq() );
       
   790             break; 
       
   791         
       
   792         default:
       
   793             AppendFormatL( iRopResponse, KPauseReply,
       
   794                 CCRRtspResponse::ERTSPRespMethodNotAllowed,  
       
   795                 iCommands[CCRRtspCommand::ERTSPCommandPAUSE]->CSeq() );
       
   796             break; 
       
   797         }
       
   798  
       
   799     SendControlData();
       
   800     }
       
   801 
       
   802 // -----------------------------------------------------------------------------
       
   803 // CCRRtspSink::ReplyToTearDownL
       
   804 //
       
   805 // 
       
   806 // -----------------------------------------------------------------------------
       
   807 //
       
   808 void CCRRtspSink::ReplyToTearDownL() 
       
   809     {
       
   810     LOG( "CCRRtspSink::ReplyToTearDownL()" );
       
   811 
       
   812     iRopResponse->Des().Zero();
       
   813     AppendFormatL( iRopResponse, KTearDownReply,
       
   814         iCommands[CCRRtspCommand::ERTSPCommandTEARDOWN]->CSeq() );
       
   815     SendControlData();
       
   816     }
       
   817 
       
   818 // -----------------------------------------------------------------------------
       
   819 // CCRRtspSink::SocketFromStream
       
   820 //
       
   821 // -----------------------------------------------------------------------------
       
   822 //      
       
   823 CCRRtspSink::TCRROPSockId CCRRtspSink::SocketFromStream(
       
   824     MCRPacketSource::TCRPacketStreamId aStreamId )
       
   825     {
       
   826     switch ( aStreamId ) 
       
   827         {
       
   828         case MCRPacketSource::EAudioStream:
       
   829             return EROPAudioSend1;
       
   830         
       
   831         case MCRPacketSource::EAudioControlStream:
       
   832             return EROPAudioSend2;
       
   833         
       
   834         case MCRPacketSource::EVideoStream:
       
   835             return EROPVideoSend1;
       
   836         
       
   837         case MCRPacketSource::EVideoControlStream:
       
   838             return EROPVideoSend2;
       
   839         
       
   840         default:
       
   841             __ASSERT_ALWAYS( 1!=2, User::Panic( KCCRRtspSink, KErrArgument ) );
       
   842             break;
       
   843         }
       
   844 
       
   845     return EROPMaxSockets; // this is never reached
       
   846     }
       
   847 
       
   848 // -----------------------------------------------------------------------------
       
   849 // CCRRtspSink::AppendL
       
   850 //
       
   851 // -----------------------------------------------------------------------------
       
   852 //      
       
   853 void CCRRtspSink::AppendL( HBufC8*& aBuffer, const TDesC8& aStr )
       
   854     {
       
   855     TPtr8 ptr( aBuffer->Des() );
       
   856     if ( ( ptr.Length() + aStr.Length() ) >= ptr.MaxLength() )
       
   857         {
       
   858         const TInt newLength( ptr.Length() + aStr.Length() + KMaxName );
       
   859         aBuffer = aBuffer->ReAllocL( newLength );
       
   860         ptr.Set( aBuffer->Des() );
       
   861         }
       
   862     
       
   863     ptr.Append( aStr );
       
   864     }
       
   865     
       
   866 // -----------------------------------------------------------------------------
       
   867 // CCRRtspSink::AppendNumL
       
   868 //
       
   869 // -----------------------------------------------------------------------------
       
   870 //      
       
   871 void CCRRtspSink::AppendNumL( HBufC8*& aBuffer, const TInt aNum )
       
   872     {
       
   873     TPtr8 ptr( aBuffer->Des() );
       
   874     if ( ( ptr.Length() + KMaxInfoName ) >= ptr.MaxLength() )
       
   875         {
       
   876         const TInt newLength( ptr.Length() + KMaxInfoName + KMaxName );
       
   877         aBuffer = aBuffer->ReAllocL( newLength );
       
   878         ptr.Set( aBuffer->Des() );
       
   879         }
       
   880     
       
   881     ptr.AppendNum( aNum );
       
   882     }
       
   883     
       
   884 // -----------------------------------------------------------------------------
       
   885 // CCRRtspSink::AppendFormatL
       
   886 //
       
   887 // -----------------------------------------------------------------------------
       
   888 //      
       
   889 void CCRRtspSink::AppendFormatL(
       
   890     HBufC8*& aBuffer,
       
   891     TRefByValue<const TDesC8> aFmt, ... )
       
   892     {
       
   893     VA_LIST list;
       
   894     VA_START( list, aFmt );
       
   895     HBufC8* buf = HBufC8::NewLC( KMaxDataSize );
       
   896     buf->Des().FormatList( aFmt, list );
       
   897     VA_END( list );
       
   898 
       
   899     TPtr8 ptr( aBuffer->Des() );
       
   900     if ( ( ptr.Length() + buf->Length() ) >= ptr.MaxLength() )
       
   901         {
       
   902         const TInt newLength( ptr.Length() + buf->Length() + KMaxName );
       
   903         aBuffer = aBuffer->ReAllocL( newLength );
       
   904         ptr.Set( aBuffer->Des() );
       
   905         }
       
   906     
       
   907     ptr.Append( *buf );
       
   908     CleanupStack::PopAndDestroy( buf );
       
   909     }
       
   910     
       
   911 // -----------------------------------------------------------------------------
       
   912 // CCRRtspSink::SendControlData
       
   913 //
       
   914 // -----------------------------------------------------------------------------
       
   915 //
       
   916 void CCRRtspSink::SendControlData()
       
   917     {
       
   918     iSockArr[EROPControl]->SendData( *iRopResponse );
       
   919     iRopResponse->Des().Zero();
       
   920     }
       
   921 
       
   922 //  End of File