dvrengine/CommonRecordingEngine/src/CCRRTSPPacketSource.cpp
branchRCL_3
changeset 22 826cea16efd9
parent 21 798ee5f1972c
child 23 13a33d82ad98
equal deleted inserted replaced
21:798ee5f1972c 22: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 Client impl.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CCRRtspPacketSource.h"
       
    22 #include "CCRPunchPacketSender.h"
       
    23 #include "CCRRtpTcpStreamer.h"
       
    24 #include "CCRRtspCommand.h"
       
    25 #include "CCRPacketBuffer.h"
       
    26 #include <ipvideo/CDvrSdpParser.h>
       
    27 #include "CCRTimer.h"
       
    28 #include <Uri16.h>
       
    29 #include <e32msgqueue.h>
       
    30 #include <centralrepository.h>
       
    31 #include <WebUtilsInternalCRKeys.h>
       
    32 #include <mmf/common/mmferrors.h>  // ROP error codes
       
    33 
       
    34 // DATA TYPES
       
    35 // ######################################################
       
    36 // WARNING: JUMBOJET-SIZED KLUDGE AHEAD:
       
    37 // ######################################################
       
    38 #define private public
       
    39 // Explanation: timestamp getter in rtcp sender report
       
    40 // class is broken beyond repair. It may be fixed but the
       
    41 // broken version is already shipped to millions of phones
       
    42 // around the world. The broken getter method can't
       
    43 // be overridden as it requires access to private part
       
    44 // of sender reports instance variables. The item we
       
    45 // need (ntp timestamp) is there intact in private instance
       
    46 // variables but there is useless getter for that.
       
    47 #include <rtcp.h>
       
    48 
       
    49 /* sender report (SR) */
       
    50 class TRtcpSRPart
       
    51     {
       
    52 public:
       
    53     TUint32 ssrc;     /**< sender generating this report */
       
    54     TUint32 ntp_sec;  /**< NTP timestamp */
       
    55     TUint32 ntp_frac; /**< Fractal seconds */
       
    56     TUint32 rtp_ts;   /**< RTP timestamp */
       
    57     TUint32 psent;    /**< packets sent */
       
    58     TUint32 osent;    /**< octets sent */
       
    59     };
       
    60 #undef private
       
    61 // ######################################################
       
    62 // Major kludge ends here.
       
    63 // ######################################################
       
    64 
       
    65 // CONSTANTS
       
    66 const TInt KCRPortNumberBase( 16670 );
       
    67 const TInt KCSeqForRtspNegoation( 42 );
       
    68 const TInt KRtspPortNumber( 554 );
       
    69 const TInt KRtpPacketVersion( 2 ); 
       
    70 const TUint KSenderReportPacketType( 0xC8 ); // 200 decimal
       
    71 const TInt KDVR10Seconds( 10000000 );
       
    72 
       
    73 // The number of sequential packets that must be received
       
    74 // before a stream is considered good. 1 means no delay, start
       
    75 // from very first packet
       
    76 const TInt KDVRMinSequential( 1 ); 
       
    77 // The maximum number of dropped packets to be considered a
       
    78 // dropout, as opposed to an ended and restarted stream.    
       
    79 const TInt KDVRMaxMisorder( 50 ); 
       
    80 // The maximum number of packets by which a packet can be delayed 
       
    81 // before it is considered dropped. 
       
    82 const TInt KDVRMaxDropOut( 3000 ); 
       
    83 _LIT( KRtspPortString, "554" );
       
    84 _LIT8( KCRCName, "N++ " );
       
    85 // Timeout for RTP/UDP reception before switching to TCP mode
       
    86 const TTimeIntervalMicroSeconds32 KCRRtspRtpUdpTimeout( 10 * 1e6 );
       
    87 // Timeout for waiting for server response to any RTSP command
       
    88 const TTimeIntervalMicroSeconds32 KCRRtspResponseTimeout( 15 * 1e6 );
       
    89 // Timeout for waiting for server response to TIERDOWN command
       
    90 const TTimeIntervalMicroSeconds32 KCRRtspTierdownTimeout( 3 * 1e6 );
       
    91 
       
    92 // ============================ MEMBER FUNCTIONS ===============================
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CCRRtspPacketSource::NewL
       
    96 // Two-phased constructor.
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 CCRRtspPacketSource* CCRRtspPacketSource::NewL(
       
   100     const SCRRtspParams& aParams,
       
   101     CCRConnection& aConnection,
       
   102     RSocketServ& aSockServer,
       
   103     MCRStreamObserver& aSessionObs,
       
   104     CCRStreamingSession& aOwningSession )
       
   105     {
       
   106     CCRRtspPacketSource* self = new( ELeave )
       
   107         CCRRtspPacketSource( aConnection, aSockServer, aSessionObs, aOwningSession );
       
   108     CleanupStack::PushL( self );
       
   109     self->ConstructL( aParams );
       
   110     CleanupStack::Pop( self );
       
   111     return self;
       
   112     }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // CCRRtspPacketSource::CCRRtspPacketSource
       
   116 // C++ default constructor can NOT contain any code, that might leave.
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 CCRRtspPacketSource::CCRRtspPacketSource(
       
   120     CCRConnection& aConnection,
       
   121     RSocketServ& aSockServer,
       
   122     MCRStreamObserver& aSessionObs,
       
   123     CCRStreamingSession& aOwningSession )
       
   124   : CCRPacketSourceBase( aOwningSession, CCRStreamingSession::ECRRtspSourceId ),
       
   125     iSockServer( aSockServer ),
       
   126     iConnection( aConnection ),
       
   127     iStage( ERTSPInit ),
       
   128     iCSeq( KCSeqForRtspNegoation ),
       
   129     iClientPort( KCRPortNumberBase ),
       
   130     iSessionId(NULL, 0 ),
       
   131     iReadyToPlay(EFalse),
       
   132     iSessionObs( aSessionObs ),
       
   133     iStartPos( KRealZero ),
       
   134     iEndPos( KRealMinusOne ),
       
   135     iUdpFound( EFalse ),
       
   136     iTrafficFound( EFalse )
       
   137     {
       
   138     // None
       
   139     }
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // CCRRtspPacketSource::ConstructL
       
   143 // Symbian 2nd phase constructor can leave.
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 void CCRRtspPacketSource::ConstructL( const SCRRtspParams& aParams )
       
   147     {
       
   148     LOG( "CCRRtspPacketSource::ConstructL() in" );
       
   149     if ( aParams.iUrl.Length() == 0 ) 
       
   150         {
       
   151         User::Leave ( KErrArgument ); 
       
   152         }
       
   153 
       
   154     iSentData = HBufC8::NewL ( KCROptionsReply().Length() + KMaxInfoName );
       
   155     iRtpTcpStreamer = CCRRtpTcpStreamer::NewL( *this );
       
   156     iRtspUri = aParams.iUrl.AllocL();
       
   157     iRtspUri8 = HBufC8::NewL( aParams.iUrl.Length());
       
   158     iRtspUri8->Des().Copy( aParams.iUrl );
       
   159     iUserName = aParams.iUserName.AllocL();
       
   160     iPassword = aParams.iPassword.AllocL();
       
   161     User::LeaveIfError( iConnection.RegisterObserver( this ) );
       
   162     iUdpReceptionTimer = CCRTimer::NewL( EPriorityLow, *this );
       
   163     iProxyServerAddr = aParams.iProxyServerAddr; 
       
   164     iProxyServerPort = aParams.iProxyServerPort; 
       
   165     DoConnectL(); // Makes no sense to construct without immediately connecting
       
   166 
       
   167     LOG( "CCRRtspPacketSource::ConstructL() out" );
       
   168     }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CCRRtspPacketSource::~CCRRtspPacketSource
       
   172 // Destructor.
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 CCRRtspPacketSource::~CCRRtspPacketSource()
       
   176     {
       
   177     LOG( "CCRRtspPacketSource::~CCRRtspPacketSource() in" );
       
   178     // Deletes everything related to session
       
   179     CleanUp();
       
   180     delete iRtspTimeout;
       
   181     delete iSentData;
       
   182     delete iAuthType;
       
   183     delete iRtspUri8;
       
   184     delete iUserName;
       
   185     delete iPassword;
       
   186     delete iNonce;
       
   187     delete iOpaque;
       
   188     delete iRealm;
       
   189     delete iRtpTcpStreamer;
       
   190     delete iUdpReceptionTimer;
       
   191     iReceiveStreams.Reset();
       
   192     iObserver = NULL;
       
   193     iConnection.UnregisterObserver( this );
       
   194     LOG( "CCRRtspPacketSource::~CCRRtspPacketSource() out" );
       
   195     }
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 // CCRRtspPacketSource::CleanUp
       
   199 // Callback method called from cleanup-cidle that just calls the actual
       
   200 // cleanup method.
       
   201 // -----------------------------------------------------------------------------
       
   202 //
       
   203 void CCRRtspPacketSource::CleanUp()
       
   204     {
       
   205     LOG( "CCRRtspPacketSource::CleanUp() in" );
       
   206     if ( iUdpReceptionTimer )
       
   207         {
       
   208         iUdpReceptionTimer->Cancel();
       
   209         }
       
   210     delete iRtspPingTimer;
       
   211     iRtspPingTimer = NULL;
       
   212 
       
   213     iRtpRecvSrcAudio.Close();
       
   214     iRtpRecvSrcVideo.Close();
       
   215     iAudioSession.Close();
       
   216     iVideoSession.Close();
       
   217     iReadyToPlay = EFalse;
       
   218     delete iSdpParser; iSdpParser = NULL;
       
   219     delete iRtspUri; iRtspUri = NULL;
       
   220     delete iRtspSock; iRtspSock = NULL;
       
   221 
       
   222     for ( TInt i( 0 ); i < ERTPMaxSockets; i++ )
       
   223         {
       
   224         delete iRTPSockArr[i];
       
   225         iRTPSockArr[i] = NULL;
       
   226         }
       
   227     for ( TInt i( 0 ); i < ERTSPLastStage; i++ )
       
   228         {
       
   229         delete iPrevCommands[i];
       
   230         iPrevCommands[i] = NULL;
       
   231         delete iResponses[i];
       
   232         iResponses[i] = NULL;
       
   233         }
       
   234     
       
   235     iSessionId.Set( NULL, 0 );
       
   236     delete iPunchPacketSenderAudio; iPunchPacketSenderAudio = NULL;
       
   237     delete iPunchPacketSenderVideo; iPunchPacketSenderVideo = NULL;
       
   238     delete iUserAgent; iUserAgent = NULL;
       
   239     delete iWapProfile; iWapProfile = NULL;
       
   240     iStartPos = KRealZero;
       
   241     iEndPos = KRealMinusOne;
       
   242     
       
   243     LOG( "CCRRtspPacketSource::CleanUp() out" );
       
   244     }
       
   245 
       
   246 // -----------------------------------------------------------------------------
       
   247 // CCRRtspPacketSource::DoConnectL
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CCRRtspPacketSource::DoConnectL( void )
       
   251     {
       
   252     if ( !iRtspUri )
       
   253         {
       
   254         User::Leave( KErrNotReady );
       
   255         }
       
   256     if ( iRtspSock )
       
   257         {
       
   258         delete iRtspSock; iRtspSock = NULL;
       
   259         }
       
   260 
       
   261     iRtspSock = CCRSock::NewL( *this, ERTPControl, iConnection.Connection(),
       
   262                                iSockServer, ETrue, ETrue );
       
   263     TUriParser uriParser;
       
   264     User::LeaveIfError( uriParser.Parse( iRtspUri->Des() ) );
       
   265     iRtspUriHost.Set( uriParser.Extract( EUriHost ) );
       
   266     TPtrC portString( KRtspPortString );
       
   267     if ( uriParser.IsPresent( EUriPort ) )
       
   268         {
       
   269         portString.Set( uriParser.Extract( EUriPort ) );
       
   270         }
       
   271     
       
   272     TLex portLex( portString );
       
   273     TInt port( KRtspPortNumber );
       
   274     if ( portLex.Val( port ) != KErrNone )
       
   275         {
       
   276         User::Leave( KErrMMInvalidURL );
       
   277         }
       
   278     if ( iProxyServerAddr.Length() && iProxyServerPort )
       
   279         {
       
   280         LOG2( "CCRRtspPacketSource::DoConnectL(), Proxy: %S port: %d",
       
   281             &iProxyServerAddr, iProxyServerPort );
       
   282         User::LeaveIfError( iRtspSock->ConnectSock( iProxyServerAddr, iProxyServerPort ) );      
       
   283         }
       
   284     else
       
   285         {
       
   286         User::LeaveIfError(iRtspSock->ConnectSock( iRtspUriHost, port ) );
       
   287         }
       
   288     iCSeq = KCSeqForRtspNegoation;
       
   289 
       
   290     TTime now;
       
   291     now.UniversalTime();
       
   292     iClientPort = 
       
   293         KCRPortNumberBase + ( ( now.DateTime().MicroSecond() / 1000 ) * 2 );
       
   294 
       
   295     // Get transport method from connection heuristics
       
   296     iTransport = ( iConnection.GetHeuristic(
       
   297         CCRConnection::EUdpStreamingBlocked ) )? ERTPOverTCP: ERTPOverUDP;
       
   298     LOG1( "CCRRtspPacketSource::DoConnectL(), RTP transport: %d (0=UDP, 1=TCP)", iTransport );
       
   299 
       
   300     // Get user agent, bandwidth and wap profile based on connection bearer (3G or not)
       
   301     TConnMonBearerType bearer = iConnection.BearerType();
       
   302     TBool is3g( iConnection.IsBearerWLANor3G( bearer ) );
       
   303 
       
   304     // Fetch wap profile from WebUtils repository
       
   305     if ( !iWapProfile )
       
   306         {
       
   307         CRepository* repository = CRepository::NewLC( KCRUidWebUtils );
       
   308         TUint32 profilekey = ( is3g )? KWebUtilsUaProf3G: KWebUtilsUaProf;
       
   309         TFileName profilebuf( KNullDesC );
       
   310         if ( !repository->Get( profilekey, profilebuf ) )
       
   311             {
       
   312             iWapProfile = HBufC8::NewL( profilebuf.Length() );
       
   313             iWapProfile->Des().Copy( profilebuf );
       
   314             }
       
   315         
       
   316         CleanupStack::PopAndDestroy( repository );
       
   317         LOG1( "CCRRtspPacketSource::DoConnectL(), iWapProfile: %S", &profilebuf );
       
   318         }
       
   319 
       
   320     // Fetch user agent
       
   321     // Should we add version information to user agent string?
       
   322     delete iUserAgent; iUserAgent = NULL;
       
   323     iUserAgent = KCRRTSPDefaultUserAgent().AllocL();
       
   324 
       
   325     // Get bandwidth from connection
       
   326     iBandwidth = iConnection.MaximumBandwidth();
       
   327 
       
   328     LOG( "CCRRtspPacketSource::DoConnectL out" );
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // CCRRtspPacketSource::URI
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 TPtr CCRRtspPacketSource::URI(void)
       
   336     {
       
   337     __ASSERT_DEBUG( iRtspUri != NULL , User::Panic( _L( "RTSP source" ), KErrBadHandle ) );
       
   338     TPtr retval ( NULL , 0 );
       
   339     if ( iRtspUri ) 
       
   340         {
       
   341         retval.Set( iRtspUri->Des() );
       
   342         }
       
   343     else
       
   344         {
       
   345         LOG( "CCRRtspPacketSource::URI iRtspUri was NULL !!!!!!!!!! " );
       
   346         }
       
   347     return retval; 
       
   348     }
       
   349 
       
   350 // -----------------------------------------------------------------------------
       
   351 // CCRRtspPacketSource::GetSdp
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 TInt CCRRtspPacketSource::GetSdp( TPtrC8& aSdp )
       
   355     {
       
   356     TInt retval( KErrNotReady );
       
   357     if ( iSdpParser )
       
   358         {
       
   359         return iSdpParser->GetSdp( aSdp );
       
   360         }
       
   361     
       
   362     return retval;
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CCRRtspPacketSource::SeqAndTS
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 TInt CCRRtspPacketSource::SeqAndTS(
       
   370     TUint& aAudioSeq,
       
   371     TUint& aAudioTS,
       
   372     TUint& aVideoSeq,
       
   373     TUint& aVideoTS )
       
   374     {
       
   375     TInt retval( KErrNotReady );
       
   376     if ( iSeqFromRtpInfoForVideo != 0 || iSeqFromRtpInfoForAudio != 0  )
       
   377         {
       
   378         aAudioSeq = iSeqFromRtpInfoForAudio;
       
   379         aAudioTS = iRTPTimeStampAudio;
       
   380         aVideoSeq = iSeqFromRtpInfoForVideo;
       
   381         aVideoTS = iRTPTimeStampVideo;
       
   382         retval = KErrNone;
       
   383         }
       
   384     
       
   385     return retval;
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CCRRtspPacketSource::PostActionL
       
   390 // -----------------------------------------------------------------------------
       
   391 //
       
   392 void CCRRtspPacketSource::PostActionL()
       
   393     {
       
   394     LOG1( "CCRRtspPacketSource::PostActionL(), SDP will be handled, iSdpParser: %d",
       
   395                                                                     iSdpParser );
       
   396     User::LeaveIfNull( iSdpParser );
       
   397     iSessionObs.StatusChanged( MCRPacketSource::ERtpStateSdpAvailable );
       
   398     }
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 // CCRRtspPacketSource::Play
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 TInt CCRRtspPacketSource::Play( const TReal& aStartPos, const TReal& aEndPos )
       
   405     {
       
   406     LOG2( "CCRRtspPacketSource::Play(), aStartPos: %f, aEndPos: %f",
       
   407                                         aStartPos, aEndPos );
       
   408     LOG2( "CCRRtspPacketSource::Play(), sent seq: %d, rec: %d", 
       
   409                                         iCSeq, iLastReceivedSeq );
       
   410     iReadyToPlay = ETrue;
       
   411     iStartPos = aStartPos;
       
   412     iEndPos = aEndPos;
       
   413     ResetStreamFlags();
       
   414 
       
   415     // In xps case we never get startpos with this method. 
       
   416     // instead setposition will be called 
       
   417     if ( iBuffer )
       
   418         {
       
   419         iBuffer->ResetBuffer();
       
   420         }    
       
   421 
       
   422     // If both audio and video sessions are closed, we
       
   423     // need to open at least one of them:
       
   424     TInt err( KErrNone );
       
   425     if ( iStage == ERTSPReadyToPlay || iStage == ERTSPPauseSent )
       
   426         {
       
   427         if ( iStage == ERTSPReadyToPlay || iCSeq == ( iLastReceivedSeq + 1 ) )
       
   428             {
       
   429             TRAP( err, SendPlayCommandL() );
       
   430             }
       
   431         else
       
   432             { 
       
   433             // We have a fast-fingered user in charge; play has been issued
       
   434             // but the previous pause has not been completed yet: postpone this
       
   435             // operation
       
   436             iPostPonedPlay = ETrue;
       
   437             }
       
   438         }
       
   439     
       
   440     return err;
       
   441     }
       
   442 
       
   443 // -----------------------------------------------------------------------------
       
   444 // CCRRtspPacketSource::Pause
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 TInt CCRRtspPacketSource::Pause()
       
   448     {
       
   449     LOG1( "CCRRTSPPacketSource::Pause() stage %d", iStage );
       
   450     TInt err( KErrNotReady );
       
   451     if ( iStage == ERTSPPlaying )
       
   452         {
       
   453         if ( iResponses[ERTSPPlaySent]->IsLiveStream() || iSdpParser->IsLiveStream() )
       
   454             {
       
   455             err = KErrNotSupported;
       
   456             }
       
   457         else
       
   458             {
       
   459             TRAP( err, SendPauseCommandL() );
       
   460             }
       
   461         }
       
   462     if ( iStage == ERTSPPauseSent )
       
   463         {
       
   464         err = KErrNone;
       
   465         }
       
   466     return err;
       
   467     }
       
   468 
       
   469 // -----------------------------------------------------------------------------
       
   470 // CCRRtspPacketSource::Stop
       
   471 // -----------------------------------------------------------------------------
       
   472 //
       
   473 TInt CCRRtspPacketSource::Stop()
       
   474     {
       
   475     LOG( "CCRRtspPacketSource::Stop()" );
       
   476     
       
   477     iReadyToPlay = EFalse;
       
   478     iPostPonedPlay = EFalse;
       
   479     iStartPos = KRealZero;
       
   480     TInt err( KErrDisconnected );
       
   481     
       
   482     if ( iStage == ERTSPPlaySent || iStage == ERTSPPlaying ||
       
   483          iStage == ERTSPPauseSent || iStage == ERTSPSetupAudioSent ||
       
   484          iStage == ERTSPSetupVideoSent )
       
   485         {
       
   486         err = KErrNone;
       
   487         if ( iRtspSock )
       
   488             {
       
   489             iRtspSock->Cancel();
       
   490             }
       
   491        
       
   492         TRAP_IGNORE( SendTearDownCommandL() ); // if this fails, we don't care
       
   493         iStage = ERTSPTearDownSent;
       
   494         StartRtspTimeout( KCRRtspTierdownTimeout );
       
   495         }
       
   496 
       
   497     return err;
       
   498     }
       
   499 
       
   500 // -----------------------------------------------------------------------------
       
   501 // CCRRtspPacketSource::SetPosition
       
   502 // -----------------------------------------------------------------------------
       
   503 
       
   504 TInt CCRRtspPacketSource::SetPosition( const TInt64 aPosition ) 
       
   505     {
       
   506     LOG1( "CCRRtspPacketSource::SetPosition(), iStartPos: %f", iStartPos );
       
   507 
       
   508     if ( aPosition == -2 )
       
   509         {
       
   510         if ( iStage != ERTSPPlaySent && iObserver )
       
   511             {
       
   512             iObserver->ConnectionStatusChange(
       
   513                 iOwningSession.SourceChecksum(),
       
   514                 ECRReadyToSeek, KErrNone );
       
   515             }
       
   516         }
       
   517     return KErrNone;
       
   518     }
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // CCRRtspPacketSource::GetRange
       
   522 // -----------------------------------------------------------------------------
       
   523 void CCRRtspPacketSource::GetRange( TReal& aLower, TReal& aUpper )
       
   524     {
       
   525     aLower = KRealZero;
       
   526     aUpper = KRealMinusOne;
       
   527 
       
   528     if ( ( iStage == ERTSPPlaySent || iStage == ERTSPPlaying ) &&
       
   529          iResponses[ERTSPPlaySent] )
       
   530          {
       
   531          iResponses[ERTSPPlaySent]->GetRange(aLower,aUpper);
       
   532          }
       
   533     }
       
   534 
       
   535 // -----------------------------------------------------------------------------
       
   536 // CCRRtspPacketSource::DataReceived
       
   537 // This is called when data is received from socket.
       
   538 // -----------------------------------------------------------------------------
       
   539 //
       
   540 void CCRRtspPacketSource::DataReceived( TInt /*aSockId*/, const TDesC8& aData )
       
   541     {
       
   542     // Find out RTCP message or RTP packet from IP packet
       
   543     iRtpTcpStreamer->DataAvailable( aData, ( iTransport == ERTPOverTCP ) );
       
   544     }
       
   545     
       
   546 // -----------------------------------------------------------------------------
       
   547 // CCRRtspPacketSource::RtspMsgAvailable
       
   548 // This is called when data is received from socket.
       
   549 // -----------------------------------------------------------------------------
       
   550 //
       
   551 void CCRRtspPacketSource::RtspMsgAvailable( const TDesC8& aData )
       
   552     {
       
   553 #if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE )
       
   554     if ( aData.Length() > 0 )
       
   555         {
       
   556         LOG1( "CCRRtspPacketSource::RtspMsgAvailable(), aData len: %d", aData.Length() );
       
   557         TName d( KNullDesC );
       
   558         for( TInt i( 0 );  i < aData.Length(); i++ )
       
   559             {
       
   560             TChar c = aData[i];
       
   561             d.Append( c );
       
   562             if ( ( i > 0 ) && ( i % 80 ) == 0 )
       
   563                 {
       
   564                 LOG1( ">%S<", &d );
       
   565                 d.Zero();
       
   566                 }
       
   567             }
       
   568         
       
   569         LOG1( ">%S<", &d );
       
   570         }
       
   571 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
   572 
       
   573     TRAPD( err, ProcessRtspResponseL( aData ) );
       
   574     if ( err )
       
   575         {
       
   576         LOG1( "CCRRtspPacketSource::RtspMsgAvailable(), ProcessRtspResponseL Leaved, err: %d", err );
       
   577         if ( err == KErrNotSupported ) 
       
   578             {
       
   579             // The response did not look like rtsp response at all. 
       
   580             // some servers decide to send rtsp commands to us so lets
       
   581             // try interpreting it as a command
       
   582             err = KErrNone; 
       
   583             TRAP( err, ProcessRTSPCommandL( aData ) )
       
   584             if ( err )
       
   585                 {
       
   586                 iOwningSession.SourceStop();                
       
   587                 }
       
   588             }
       
   589         else
       
   590             {
       
   591             iOwningSession.SourceStop();
       
   592             }
       
   593         }
       
   594     }
       
   595 
       
   596 // -----------------------------------------------------------------------------
       
   597 // CCRRtspPacketSource::SockStatusChange
       
   598 // This is called when socket status changes.
       
   599 // -----------------------------------------------------------------------------
       
   600 //
       
   601 void CCRRtspPacketSource::SockStatusChange(
       
   602     TInt aSockId, 
       
   603     CCRSock::TCRSockStatus aStatus,
       
   604     TInt aError )
       
   605     {
       
   606 #if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE )
       
   607     if ( aStatus == CCRSock::EFailed )
       
   608         {
       
   609         LOG3( "CCRRtspPacketSource::SockStatusChange(), aSockId: %d,  aStatus: %d, aError: %d",
       
   610                                                         aSockId, aStatus, aError );
       
   611         }
       
   612 #else // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
   613     ( void )aSockId;
       
   614     ( void )aError;
       
   615 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
   616 
       
   617     if ( aStatus == CCRSock::EFailed )
       
   618         {
       
   619         // Ask session to perform cleanup
       
   620         iOwningSession.SourceStop();
       
   621 
       
   622         if ( iStage == ERTSPInit && aSockId == ERTPControl && aError == KErrCouldNotConnect )
       
   623             {
       
   624             // map error to different error id, so we can know that showing reconnect query is pointless.
       
   625             aError = KErrEof;
       
   626             }
       
   627         
       
   628         // Inform the observer that there is a problem. Exclude case where we're closing
       
   629         // and the error is KErrEof
       
   630         if ( ! ( iStage == ERTSPTearDownSent && aError == KErrEof ) ) 
       
   631             {
       
   632             if ( iObserver )
       
   633                 {
       
   634                 iObserver->ConnectionStatusChange(
       
   635                     iOwningSession.SourceChecksum(), ECRConnectionError, aError );
       
   636                 }
       
   637             }
       
   638         else
       
   639             {
       
   640             LOG( "CCRRtspPacketSource::SockStatusChange(), eof in closing: normal" );
       
   641             }
       
   642         }
       
   643     else if ( aSockId == ERTPControl && aStatus == CCRSock::EIdle && 
       
   644               iStage == ERTSPInit )
       
   645         {
       
   646         // Called once from here for lifetime of this object
       
   647         TRAPD( err, SendRtspCommandL() ); 
       
   648         if ( err )
       
   649             {
       
   650             LOG1( "CCRRtspPacketSource::SockStatusChange(), SendRtspCommandL Leaved: %d", err );
       
   651     
       
   652             // Ask session to perform cleanup
       
   653             iOwningSession.SourceStop();
       
   654             }
       
   655         }
       
   656     }
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // CCRRtspPacketSource::RtpTcpPacketAvailable
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 void CCRRtspPacketSource::RtpTcpPacketAvailable(
       
   663     TInt aChannel,
       
   664     const TDesC8& aPacket )
       
   665     {
       
   666     // Map embedded TCP channel to streamid:
       
   667     // video: channel=(0,1) --> id=(2,3)
       
   668     // audio: channel=(2,3) --> id=(0,1)  when video present
       
   669     // audio: channel=(0,1) --> id=(0,1)  when audio only
       
   670     TInt mappedChannel( ( iSdpParser->VideoControlAddr().Length() )? 
       
   671                         ( aChannel + 2 ) % 4: aChannel );
       
   672     MCRPacketSource::TCRPacketStreamId streamid( 
       
   673         ( MCRPacketSource::TCRPacketStreamId )( mappedChannel ) );
       
   674 
       
   675     iBuffer->AddPacket( streamid, aPacket );
       
   676     }
       
   677 
       
   678 // -----------------------------------------------------------------------------
       
   679 // CCRRtspPacketSource::ForwardRtpTcpChunk
       
   680 // -----------------------------------------------------------------------------
       
   681 //
       
   682 void CCRRtspPacketSource::ForwardRtpTcpChunck( const TDesC8& aChunk )
       
   683     {
       
   684     if ( iRtspSock )
       
   685         {
       
   686         iRtspSock->SendData( aChunk );
       
   687         }
       
   688     }
       
   689 
       
   690 // -----------------------------------------------------------------------------
       
   691 // CCRRtspPacketSource::TimerExpired
       
   692 // -----------------------------------------------------------------------------
       
   693 //
       
   694 void CCRRtspPacketSource::TimerExpired( CCRTimer* )
       
   695     {
       
   696     LOG( "CCRRtspPacketSource::TimerExpired: RTP/UDP timer expired, switching to RTP/TCP" );
       
   697 
       
   698     if ( !iUdpFound )
       
   699         {            
       
   700         // Signal heuristic for TCP streaming
       
   701         LOG( "CCRRtspPacketSource::TimerExpired - Switch to TCP" );
       
   702         iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, ETrue );
       
   703         }
       
   704     else
       
   705         {
       
   706         // We had UDP before in this session but now it is lost for some reason.
       
   707         // Try UDP again.
       
   708         
       
   709         // Flag UDP found away
       
   710         iUdpFound = EFalse;
       
   711         iTrafficFound = EFalse;
       
   712         
       
   713         // Clear stream followup
       
   714         iReceiveStreams.Reset();
       
   715         
       
   716         LOG( "CCRRtspPacketSource::TimerExpired - Trying UDP again" );
       
   717         }
       
   718     
       
   719     // Notify client to close us and start a new session
       
   720     if ( iObserver )
       
   721         {
       
   722         // Notify client
       
   723         iObserver->ConnectionStatusChange(
       
   724             iOwningSession.SourceChecksum(), ECRSwitchingToTcp, KErrNone );
       
   725         }
       
   726     else
       
   727         {
       
   728         // If no client observer, teardown and cleanup ourselves
       
   729         iPostPonedPlay = EFalse; 
       
   730         TRAPD( err, SendTearDownCommandL() );
       
   731         if ( err != KErrNone )
       
   732             {
       
   733             LOG1( "CCRRtspPacketSource::TimerExpired() Send TEARDOWN failed: %d", err );
       
   734             }
       
   735     
       
   736         CleanUp();
       
   737         iSessionObs.StatusChanged( MCRPacketSource::ERtpStateClosing );
       
   738         }
       
   739     }
       
   740 
       
   741 // -----------------------------------------------------------------------------
       
   742 // CCRRtspPacketSource::ProcessRTSPCommandL
       
   743 // -----------------------------------------------------------------------------
       
   744 //
       
   745 void CCRRtspPacketSource::ProcessRTSPCommandL( const TDesC8& aData )
       
   746     {
       
   747     LOG1( "CCRRtspPacketSource::ProcessRTSPCommandL(), iStage: %d", ( int )iStage );
       
   748 
       
   749     CCRRtspCommand* cmd = CCRRtspCommand::NewL();
       
   750     CleanupStack::PushL( cmd );
       
   751     cmd->TryParseL( aData );
       
   752     
       
   753     switch ( cmd->Command() )
       
   754         {
       
   755         case CCRRtspCommand::ERTSPCommandOPTIONS:
       
   756             iSentData->Des().Format( KCROptionsReply, cmd->CSeq() );
       
   757             iRtspSock->SendData( iSentData->Des() );
       
   758             break;
       
   759             
       
   760         default:
       
   761             // Server sent us a command and it is not options. 
       
   762             // for sure they want us to stop ; is there 
       
   763             iOwningSession.SourceStop();
       
   764             break;
       
   765         }
       
   766     
       
   767     CleanupStack::PopAndDestroy( cmd );
       
   768     }
       
   769 
       
   770 // -----------------------------------------------------------------------------
       
   771 // CCRRtspPacketSource::ProcessRtspResponseL
       
   772 // -----------------------------------------------------------------------------
       
   773 //
       
   774 void CCRRtspPacketSource::ProcessRtspResponseL( const TDesC8& aData )
       
   775     {
       
   776     LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), iStage: %d", iStage );
       
   777 
       
   778     // Cancel timeout timer
       
   779     if ( iRtspTimeout )
       
   780         {
       
   781         iRtspTimeout->Cancel();
       
   782         }
       
   783 
       
   784     // The server responded to our TEARDOWN command. No need to parse the response
       
   785     // since we don't care what the server said. Ask session to clean us up.
       
   786     if ( iStage == ERTSPTearDownSent )
       
   787         {
       
   788         iOwningSession.SourceStop();
       
   789         return;
       
   790         }
       
   791 
       
   792     // First parse response
       
   793     CCRRtspResponse* resp = CCRRtspResponse::NewL();
       
   794     CleanupStack::PushL( resp );
       
   795     resp->TryParseL( aData );
       
   796     
       
   797     // Then find the command that this resp is associated with:
       
   798     iLastReceivedSeq = resp->CSeq(); 
       
   799     TBool commandFound( EFalse );
       
   800     for ( TInt i( 0 ); i < ERTSPLastStage && !commandFound; i++ )
       
   801         {
       
   802         LOG2( "CCRRtspPacketSource:: prevcommand stage: %d cseq: %d", 
       
   803             i, ( iPrevCommands[i] )? iPrevCommands[i]->CSeq(): KErrNotFound );
       
   804         
       
   805         if ( iPrevCommands[i] && ( iPrevCommands[i]->CSeq() == resp->CSeq() ) )
       
   806             {
       
   807             LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), matching command: %d", i );
       
   808             LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), cseq was: %d", resp->CSeq() );
       
   809             delete iResponses[i];
       
   810             CleanupStack::Pop( resp );
       
   811             iResponses[i] = resp;
       
   812             commandFound = ETrue;
       
   813             if ( i == ERTSPOptSent )
       
   814                 {
       
   815                 // Process options no further, used only for ping here
       
   816                 return; 
       
   817                 }
       
   818             }
       
   819         }
       
   820     
       
   821     // Delete response if sequency not match
       
   822     if ( !commandFound )
       
   823         {
       
   824         CleanupStack::PopAndDestroy( resp );
       
   825         LOG1( "CCRRtspPacketSource::ProcessRtspResponseL(), Command not found, cseq: %d", resp->CSeq() );
       
   826         }
       
   827     else
       
   828         {
       
   829         if ( iResponses[iStage]->StatusCode() ==  CCRRtspResponse::ERTSPRespOK ||      // 200
       
   830              iResponses[iStage]->StatusCode() ==  CCRRtspResponse::ERTSPRespCreated )  // 201
       
   831             {
       
   832             // Extract useful information from response depending on stage:
       
   833             switch ( iStage )
       
   834                 {
       
   835                 case ERTSPSetupAudioSent: // From setups take session id
       
   836                 case ERTSPSetupVideoSent:
       
   837                     if ( !iSessionId.Ptr() )
       
   838                         {
       
   839                         iResponses[iStage]->SessionId( iSessionId );
       
   840                         }
       
   841                     // Check for sdp parser and send punch packets for UDP transport
       
   842                     // (TCP or multicast: session setup and PLAY in SendRTSPCommand)
       
   843                     if ( iSdpParser && iTransport == ERTPOverUDP )
       
   844                         {
       
   845                         // If we see that we don't need to send further setups,
       
   846                         // do send punch packets now.
       
   847                         if ( ( iSdpParser->VideoControlAddr().Length() && // if we have video
       
   848                              iResponses[ERTSPSetupVideoSent] &&   // and we have video se tup
       
   849                              iSdpParser->AudioControlAddr().Length() &&   // and we have audio
       
   850                              iResponses[ERTSPSetupAudioSent] ) || // and we have audio set up or...
       
   851                            ( !iSdpParser->VideoControlAddr().Length() &&  // if we have no video
       
   852                              !iResponses[ERTSPSetupVideoSent] &&  // and we've video not set up
       
   853                              iSdpParser->AudioControlAddr().Length() &&   // and it shows we have audio
       
   854                              iResponses[ERTSPSetupAudioSent] ) || // and we've audio set up or...
       
   855                            ( iSdpParser->VideoControlAddr().Length() &&   // if we have video
       
   856                              iResponses[ERTSPSetupVideoSent] &&   // and we have video set up
       
   857                              !iSdpParser->AudioControlAddr().Length() &&  // and we have no audio
       
   858                              !iResponses[ERTSPSetupAudioSent] ) ) // and we have no audio set up
       
   859                             {
       
   860                             SendPunchPacketsL();
       
   861                             }
       
   862                         }
       
   863                     
       
   864                     // Notify sink that SETUP repply received
       
   865                     iSessionObs.StatusChanged(
       
   866                         MCRPacketSource::ERtpStateSetupRepply );
       
   867                     break;
       
   868                 
       
   869                 case ERTSPDescSent: // From desc take sdp
       
   870                     if ( iObserver && iResponses[iStage]->ContentLen() <= 0 )
       
   871                         { 
       
   872                         // This should not happen
       
   873                         if ( iObserver ) 
       
   874                             {
       
   875                             iObserver->ConnectionStatusChange(
       
   876                                 iOwningSession.SourceChecksum(), ECRConnectionError, KErrUnderflow );
       
   877                             }
       
   878                         iOwningSession.SourceStop();
       
   879                         }
       
   880                     else
       
   881                         {
       
   882                         delete iSdpParser; iSdpParser = NULL;
       
   883                         iSdpParser = CDvrSdpParser::NewL();
       
   884                         if ( iResponses[iStage]->ContentBase().Length() )
       
   885                             {
       
   886                             iSdpParser->TryParseL( iResponses[iStage]->Content(), 
       
   887                                                    iResponses[iStage]->ContentBase() );
       
   888                             }
       
   889                         else
       
   890                             {
       
   891                             iSdpParser->TryParseL( iResponses[iStage]->Content(), 
       
   892                                                    iRtspUri8->Des() );
       
   893                             }                  
       
   894                         // Check for multicast address in SDP
       
   895                         if ( iSdpParser->IsMultiCastSdp() )
       
   896                             {
       
   897                             iTransport = ERTPOverMulticast;
       
   898                             }
       
   899                         if ( iObserver && iSdpParser->IsRealMediaContent() )
       
   900                             {
       
   901                             iObserver->ConnectionStatusChange(
       
   902                                 iOwningSession.SourceChecksum(),
       
   903                                 ECRStreamIsRealMedia, KErrNotSupported );
       
   904                             iOwningSession.SourceStop();
       
   905                             return; // Make sure we don't continue with SETUP commands
       
   906                             }
       
   907                         else // do not send realmedia sdp to sinks
       
   908                             { 
       
   909                             if ( iObserver && iSdpParser->IsLiveStream() )
       
   910                                 {
       
   911                                 iObserver->ConnectionStatusChange(
       
   912                                     iOwningSession.SourceChecksum(),
       
   913                                     ECRStreamIsLiveStream, KErrNone );
       
   914                                 }
       
   915                             
       
   916                             // then check for bandwidth requirements even before we start:
       
   917                             if ( iObserver )
       
   918                                 {
       
   919                                 // Unknown bitrate or bandwidth are returned as zero.
       
   920                                 // Bitrates in kbit/s
       
   921                                 TInt bitrate( iSdpParser->VideoBitrate() + 
       
   922                                               iSdpParser->AudioBitrate() );
       
   923                                 TInt bandwidth( iConnection.MaximumBandwidth() / 1000 );
       
   924                                 if ( bitrate && bandwidth && bandwidth < bitrate )
       
   925                                     {
       
   926                                     LOG2( "CCRRtspPacketSource::ProcessRtspResponseL(), bitrate:%d, bandwidth: %d -> NotEnoughBandwidth",
       
   927                                                                                         bitrate, bandwidth);
       
   928                                     iObserver->ConnectionStatusChange(
       
   929                                         iOwningSession.SourceChecksum(),
       
   930                                         ECRNotEnoughBandwidth, KErrNone );
       
   931                                     return; // Make sure we don't tell sinks anything about
       
   932                                             // sdp that has too high bitrate for our network bearer
       
   933                                     }
       
   934                                 }
       
   935                             
       
   936                             // But if we didn't have realmedia stream and the bandwidth check
       
   937                             // is also all right, then go on and tell the sinks ->
       
   938                             iSessionObs.StatusChanged(
       
   939                                 MCRPacketSource::ERtpStateSdpAvailable );
       
   940                             }
       
   941                         }
       
   942                     break;
       
   943                 
       
   944                 case ERTSPPlaySent:
       
   945                     {
       
   946                     CCRRtspResponse::SRTPInfoHeader rtpInfo;
       
   947                     iResponses[ERTSPPlaySent]->RTPInfoHeader( rtpInfo );
       
   948 
       
   949                     TPtrC8 videoAddr ( NULL, 0 ); 
       
   950                     if ( iSdpParser->VideoControlAddr().Length() ) 
       
   951                         {
       
   952                         videoAddr.Set ( iSdpParser->VideoControlAddr() );
       
   953                         }
       
   954                     TPtrC8 audioAddr ( NULL , 0 );
       
   955                     if ( iSdpParser->AudioControlAddr().Length() ) 
       
   956                         {
       
   957                         audioAddr.Set ( iSdpParser->AudioControlAddr() );
       
   958                         }
       
   959                     
       
   960                     if ( iSdpParser->VideoControlAddr().Length() && 
       
   961                         rtpInfo.iFirstURL.Length() &&
       
   962                         videoAddr.Find( rtpInfo.iFirstURL ) >= 0 )
       
   963                         {
       
   964                         iRTPTimeStampVideo = rtpInfo.iFirstTS ? rtpInfo.iFirstTS : 1;
       
   965                         iSeqFromRtpInfoForVideo = rtpInfo.iFirstSeq;
       
   966                         }
       
   967                     if ( iSdpParser->VideoControlAddr().Length() && 
       
   968                          rtpInfo.iSecondURL.Length() &&
       
   969                          videoAddr.Find( rtpInfo.iSecondURL ) >= 0 )
       
   970                         {
       
   971                         iRTPTimeStampVideo = rtpInfo.iSecondTS ? rtpInfo.iSecondTS : 1;
       
   972                         iSeqFromRtpInfoForVideo = rtpInfo.iSecondSeq;
       
   973                         }
       
   974                     if ( iSdpParser->AudioControlAddr().Length() && 
       
   975                          rtpInfo.iFirstURL.Length() &&
       
   976                          audioAddr.Find( rtpInfo.iFirstURL) >= 0 )
       
   977                         {
       
   978                         iRTPTimeStampAudio = rtpInfo.iFirstTS ? rtpInfo.iFirstTS : 1;
       
   979                         iSeqFromRtpInfoForAudio = rtpInfo.iFirstSeq;
       
   980                         }
       
   981                     if ( iSdpParser->AudioControlAddr().Length() && 
       
   982                          rtpInfo.iSecondURL.Length() &&
       
   983                          audioAddr.Find( rtpInfo.iSecondURL) >= 0 )
       
   984                         {
       
   985                         iRTPTimeStampAudio = rtpInfo.iSecondTS ? rtpInfo.iSecondTS : 1;
       
   986                         iSeqFromRtpInfoForAudio = rtpInfo.iSecondSeq;
       
   987                         }
       
   988 
       
   989                     // ok, if we don't have rtp-info header, we don't know yet.
       
   990                     if (  rtpInfo.iFirstURL.Length() == 0 &&
       
   991                           rtpInfo.iSecondURL.Length() == 0 )
       
   992                         {
       
   993                         iNoRtpInfoHeader++;
       
   994                         }
       
   995                     else    
       
   996                         {
       
   997                         // We have RTP-info, so control stream is no longer mandatory
       
   998                         // Mark control streams as "found"                        
       
   999                         StreamFound( EAudioControlStream );
       
  1000                         StreamFound( EVideoControlStream );
       
  1001                         //StreamFound( ESubTitleControlStream );
       
  1002                         
       
  1003                         iSessionObs.StatusChanged( 
       
  1004                             MCRPacketSource::ERtpStateSeqAndTSAvailable );
       
  1005                         }
       
  1006                     
       
  1007                     // Live state
       
  1008                     if ( iResponses[ERTSPPlaySent]->IsLiveStream() || iSdpParser->IsLiveStream() ) 
       
  1009                         {
       
  1010                         if ( iObserver )
       
  1011                             {
       
  1012                             iObserver->ConnectionStatusChange(
       
  1013                                 iOwningSession.SourceChecksum(),
       
  1014                                 ECRStreamIsLiveStream, KErrNone );
       
  1015                             }
       
  1016                         }
       
  1017                     
       
  1018                     // Notify seeking
       
  1019                     if ( iObserver )
       
  1020                         {
       
  1021                         iObserver->ConnectionStatusChange(
       
  1022                             iOwningSession.SourceChecksum(),
       
  1023                             ECRReadyToSeek, KErrNone );
       
  1024                         }
       
  1025                     }
       
  1026                     break;
       
  1027                     
       
  1028             default:
       
  1029                 // by default extract no information
       
  1030                 break;
       
  1031                 }
       
  1032                 
       
  1033             // Then continue with business:
       
  1034             SendRtspCommandL(); // will change iStage also
       
  1035             }
       
  1036             
       
  1037         // Authentication needed..
       
  1038         else if ( iResponses[iStage]->StatusCode() ==  
       
  1039                   CCRRtspResponse::ERTSPRespUnauthorized || // 401
       
  1040                   iResponses[iStage]->StatusCode() ==
       
  1041                   CCRRtspResponse::ERTSPRespProxyAuthenticationRequired )  // 407
       
  1042             {
       
  1043             iAuthFailedCount++;
       
  1044             if ( iUserName && 
       
  1045                  iUserName->Length() && 
       
  1046                  iPassword && 
       
  1047                  iAuthFailedCount == 1 )
       
  1048                 {
       
  1049                 iAuthenticationNeeded = ETrue;
       
  1050                 iAuthType = iResponses[iStage]->AuthenticationTypeL().AllocL();
       
  1051                 iRealm = iResponses[iStage]->RealmL().AllocL();
       
  1052                 iOpaque = iResponses[iStage]->OpaqueL().AllocL();
       
  1053                 iNonce = iResponses[iStage]->NonceL().AllocL();
       
  1054                 SendAuthDescribeL();
       
  1055                 }
       
  1056             else
       
  1057                 {
       
  1058                 iAuthFailedCount = 0;
       
  1059                 LOG( "CCRRtspPacketSource::ProcessRtspResponseL() Authentication failure !" );
       
  1060                 
       
  1061                 // Cleanup
       
  1062                 iOwningSession.SourceStop();
       
  1063                 if ( iObserver )
       
  1064                     {
       
  1065                     iObserver->ConnectionStatusChange(
       
  1066                         iOwningSession.SourceChecksum(), 
       
  1067                         ECRAuthenticationNeeded, KErrNone );
       
  1068                     }
       
  1069                 }
       
  1070             }
       
  1071         else if ( iResponses[iStage]->StatusCode() ==  CCRRtspResponse::ERTSPRespUnsupportedTransport )  // 461
       
  1072             {            
       
  1073             LOG1( "CCRRtspPacketSource::ProcessRtspResponseL() - Unsupported Transport: %d", iTransport );
       
  1074                         
       
  1075             if ( iConnection.GetHeuristic( CCRConnection::EUdpStreamingBlocked ) )
       
  1076                 {
       
  1077                 // Using TCP, change to UDP                                
       
  1078                 LOG( "CCRRtspPacketSource::ProcessRtspResponseL() - Change TCP to UDP" );
       
  1079                 iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, EFalse );                
       
  1080                 // Notify observer at client side:
       
  1081                 ProcessRtspErrorResponseL( iResponses[iStage]->StatusCode() );
       
  1082                 }
       
  1083             else
       
  1084                 {
       
  1085                 // Using UDP, change to TCP
       
  1086                 LOG( "CCRRtspPacketSource::ProcessRtspResponseL() - Change UDP to TCP");
       
  1087                 iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, ETrue );
       
  1088                 // Notify observer at client side:
       
  1089                 ProcessRtspErrorResponseL( iResponses[iStage]->StatusCode() );
       
  1090                 }
       
  1091             }
       
  1092         else
       
  1093             {
       
  1094             // before doing cleanup, notify observer at client side:
       
  1095             ProcessRtspErrorResponseL( iResponses[iStage]->StatusCode() );
       
  1096             }
       
  1097         }
       
  1098     }
       
  1099 
       
  1100 // -----------------------------------------------------------------------------
       
  1101 // CCRRtspPacketSource::ProcessRtspErrorResponseL
       
  1102 // -----------------------------------------------------------------------------
       
  1103 //
       
  1104 void CCRRtspPacketSource::ProcessRtspErrorResponseL(
       
  1105     CCRRtspResponse::TResponseCode aErrorCode )
       
  1106     {
       
  1107     SCRQueueEntry entry;
       
  1108     entry.iMsg = ECRMsgQueueConnectionError;
       
  1109 
       
  1110     switch ( aErrorCode )
       
  1111         {
       
  1112         case CCRRtspResponse::ERTSPRespLowOnStorageSpace:
       
  1113             entry.iErr = KErrGeneral;
       
  1114             break;
       
  1115         
       
  1116         case CCRRtspResponse::ERTSPRespMultipleChoices:
       
  1117             entry.iErr = KErrGeneral;
       
  1118             break;
       
  1119         
       
  1120         case CCRRtspResponse::ERTSPRespMovedPermanently:
       
  1121             entry.iErr = KErrNotFound;
       
  1122             break;
       
  1123         
       
  1124         case CCRRtspResponse::ERTSPRespMovedTemporarily:
       
  1125             entry.iErr = KErrNotFound;
       
  1126             break;
       
  1127         
       
  1128         case CCRRtspResponse::ERTSPRespSeeOther:
       
  1129             entry.iErr = KErrGeneral;
       
  1130             break;
       
  1131         
       
  1132         case CCRRtspResponse::ERTSPRespNotModified:
       
  1133             entry.iErr = KErrGeneral;
       
  1134             break;
       
  1135         
       
  1136         case CCRRtspResponse::ERTSPRespUseProxy:
       
  1137             entry.iErr = KErrGeneral;
       
  1138             break;
       
  1139         
       
  1140         case CCRRtspResponse::ERTSPRespBadRequest:
       
  1141             entry.iErr = KErrGeneral;
       
  1142             break;
       
  1143         
       
  1144         case CCRRtspResponse::ERTSPRespPaymentRequired:
       
  1145             entry.iErr = KErrGeneral;
       
  1146             break;
       
  1147         
       
  1148         case CCRRtspResponse::ERTSPRespForbidden:
       
  1149             entry.iErr = KErrGeneral;
       
  1150             break;
       
  1151         
       
  1152         case CCRRtspResponse::ERTSPRespGone:
       
  1153         case CCRRtspResponse::ERTSPRespConferenceNotFound:
       
  1154         case CCRRtspResponse::ERTSPRespNotFound:
       
  1155             entry.iErr = KErrNotFound;
       
  1156             break;
       
  1157         
       
  1158         case CCRRtspResponse::ERTSPRespMethodNotAllowed:
       
  1159             entry.iErr = KErrGeneral;
       
  1160             break;
       
  1161         
       
  1162         case CCRRtspResponse::ERTSPRespNotAcceptable:
       
  1163             entry.iErr = KErrGeneral;
       
  1164             break;
       
  1165         
       
  1166         case CCRRtspResponse::ERTSPRespRequestTimeOut:
       
  1167             entry.iErr = KErrTimedOut;
       
  1168             break;
       
  1169         
       
  1170         case CCRRtspResponse::ERTSPRespLengthRequired:
       
  1171             entry.iErr = KErrGeneral;
       
  1172             break;
       
  1173         
       
  1174         case CCRRtspResponse::ERTSPRespPreconditionFailed:
       
  1175             entry.iErr = KErrGeneral;
       
  1176             break;
       
  1177         
       
  1178         case CCRRtspResponse::ERTSPRespRequestEntityTooLarge:
       
  1179             entry.iErr = KErrGeneral;
       
  1180             break;
       
  1181         
       
  1182         case CCRRtspResponse::ERTSPRespRequestURITooLarge:
       
  1183             entry.iErr = KErrGeneral;
       
  1184             break;
       
  1185                 
       
  1186         case CCRRtspResponse::ERTSPRespParameterNotUnderstood:
       
  1187             entry.iErr = KErrArgument;
       
  1188             break;
       
  1189         
       
  1190         case CCRRtspResponse::ERTSPRespNotEnoughBandwidth:
       
  1191             entry.iErr = KErrGeneral;
       
  1192             break;
       
  1193         
       
  1194         case CCRRtspResponse::ERTSPRespSessionNotFound:
       
  1195             entry.iErr = KErrCouldNotConnect;
       
  1196             break;
       
  1197         
       
  1198         case CCRRtspResponse::ERTSPRespMethodNotValidInThisState:
       
  1199             entry.iErr = KErrGeneral;
       
  1200             break;
       
  1201         
       
  1202         case CCRRtspResponse::ERTSPRespHeaderFieldNotValidForResource:
       
  1203             entry.iErr = KErrGeneral;
       
  1204             break;
       
  1205         
       
  1206         case CCRRtspResponse::ERTSPRespInvalidRange:
       
  1207             entry.iErr = KErrGeneral;
       
  1208             break;
       
  1209         
       
  1210         case CCRRtspResponse::ERTSPRespParameterIsReadOnly:
       
  1211             entry.iErr = KErrGeneral;
       
  1212             break;
       
  1213         
       
  1214         case CCRRtspResponse::ERTSPRespAggregateOperationNotAllowed:
       
  1215             entry.iErr = KErrGeneral;
       
  1216             break;
       
  1217         
       
  1218         case CCRRtspResponse::ERTSPRespOnlyAggregateOperationAllowed:
       
  1219             entry.iErr = KErrGeneral;
       
  1220             break;
       
  1221         
       
  1222         case CCRRtspResponse::ERTSPRespUnsupportedTransport:
       
  1223             entry.iErr = KErrCouldNotConnect;
       
  1224             break;
       
  1225         
       
  1226         case CCRRtspResponse::ERTSPRespDestinationUnreachable:
       
  1227             entry.iErr = KErrCouldNotConnect;
       
  1228             break;
       
  1229         
       
  1230         case CCRRtspResponse::ERTSPRespInternalServerError:
       
  1231             entry.iErr = KErrGeneral;
       
  1232             break;
       
  1233         
       
  1234         case CCRRtspResponse::ERTSPRespNotImplemented:
       
  1235             entry.iErr = KErrGeneral;
       
  1236             break;
       
  1237         
       
  1238         case CCRRtspResponse::ERTSPRespBadGateway:
       
  1239             entry.iErr = KErrGeneral;
       
  1240             break;
       
  1241         
       
  1242         case CCRRtspResponse::ERTSPRespServiceUnavailable:
       
  1243             entry.iErr = KErrCouldNotConnect;
       
  1244             break;
       
  1245         
       
  1246         case CCRRtspResponse::ERTSPRespGatewayTimeOut:
       
  1247             entry.iErr = KErrGeneral;
       
  1248             break;
       
  1249         
       
  1250         case CCRRtspResponse::ERTSPRespUnsupportedMediaType:
       
  1251         case CCRRtspResponse::ERTSPRespOptionNotSupported:
       
  1252         case CCRRtspResponse::ERTSPRespRTSPVersionNotSupported:
       
  1253             entry.iErr = KErrNotSupported;
       
  1254             break;
       
  1255         
       
  1256         default:
       
  1257             entry.iErr = KErrGeneral;
       
  1258             break;
       
  1259         }
       
  1260 
       
  1261     if ( iObserver )
       
  1262         {
       
  1263         iObserver->ConnectionStatusChange(
       
  1264             iOwningSession.SourceChecksum(), ECRConnectionError, entry.iErr );
       
  1265         }
       
  1266 
       
  1267     // Try tear down first
       
  1268     if ( Stop() == KErrDisconnected )
       
  1269         {
       
  1270         iOwningSession.SourceStop();
       
  1271         }
       
  1272     }
       
  1273 
       
  1274 // -----------------------------------------------------------------------------
       
  1275 // CCRRtspPacketSource::StartRtspTimeout
       
  1276 // Starts RTSP command response timeout.
       
  1277 // -----------------------------------------------------------------------------
       
  1278 //
       
  1279 void CCRRtspPacketSource::StartRtspTimeout( TTimeIntervalMicroSeconds32 aTime )
       
  1280     {
       
  1281     // Start a timeout timer to wait for the server to respond.
       
  1282     // If the server doesn't respond in time, cleanup will be initialized.
       
  1283     if ( !iRtspTimeout )
       
  1284         {
       
  1285         TRAPD( err, iRtspTimeout = 
       
  1286             CPeriodic::NewL( CActive::EPriorityStandard ) );
       
  1287         if ( err != KErrNone )
       
  1288             {
       
  1289             // Timer creation failed, start cleanup immediately
       
  1290             iOwningSession.SourceStop();
       
  1291             }
       
  1292         }
       
  1293     else
       
  1294         {
       
  1295         iRtspTimeout->Cancel(); 
       
  1296         }
       
  1297 
       
  1298     // Start timeout timer
       
  1299     iRtspTimeout->Start( 
       
  1300         aTime,
       
  1301         aTime,
       
  1302         TCallBack( RtspTimeoutCallback, this ) );
       
  1303     }
       
  1304 
       
  1305 // -----------------------------------------------------------------------------
       
  1306 // CCRRtspPacketSource::RtspTimeoutCallback
       
  1307 // Callback for RTSP response timeout. Just ask session to start cleanup
       
  1308 // -----------------------------------------------------------------------------
       
  1309 //
       
  1310 TInt CCRRtspPacketSource::RtspTimeoutCallback( TAny* aPtr )
       
  1311     {
       
  1312     LOG( "CCRRtspPacketSource::RtspTimeoutCallback()" );
       
  1313 
       
  1314     CCRRtspPacketSource* self = static_cast<CCRRtspPacketSource*>( aPtr );
       
  1315     self->iRtspTimeout->Cancel();
       
  1316     self->iOwningSession.SourceStop();
       
  1317     return 0;
       
  1318     }
       
  1319 
       
  1320 // -----------------------------------------------------------------------------
       
  1321 // CCRRtspPacketSource::SendRtspCommandL
       
  1322 // -----------------------------------------------------------------------------
       
  1323 //
       
  1324 void CCRRtspPacketSource::SendRtspCommandL()
       
  1325     {
       
  1326     LOG1( "CCRRtspPacketSource::SendRtspCommandL(), iStage: %d", iStage );
       
  1327     
       
  1328     if ( iPostPonedPlay )
       
  1329         {
       
  1330         iPostPonedPlay = EFalse;
       
  1331         Play( iStartPos, iEndPos );
       
  1332         }
       
  1333     else
       
  1334         {
       
  1335         switch ( iStage )
       
  1336             {
       
  1337             case ERTSPInit:
       
  1338             case ERTSPOptSent:
       
  1339                 {
       
  1340                 delete iPrevCommands[ERTSPDescSent];
       
  1341                 iPrevCommands[ERTSPDescSent] = NULL;
       
  1342                 iPrevCommands[ERTSPDescSent] = CCRRtspCommand::NewL();
       
  1343                 iPrevCommands[ERTSPDescSent]->SetCommand( 
       
  1344                     CCRRtspCommand::ERTSPCommandDESCRIBE );
       
  1345                 
       
  1346                 TPtrC8 uriDes ( iRtspUri8->Des() );
       
  1347                 iPrevCommands[ERTSPDescSent]->SetURL( uriDes );
       
  1348                 iPrevCommands[ERTSPDescSent]->SetCSeq( iCSeq++ );
       
  1349                 if ( iUserAgent )
       
  1350                     {
       
  1351                     iPrevCommands[ERTSPDescSent]->SetUserAgentL( *iUserAgent );
       
  1352                     }
       
  1353                 if ( iWapProfile )
       
  1354                     {
       
  1355                     iPrevCommands[ERTSPDescSent]->SetWapProfileL( *iWapProfile );
       
  1356                     }
       
  1357                 if ( iBandwidth )
       
  1358                     {
       
  1359                     iPrevCommands[ERTSPDescSent]->SetBandwidth( iBandwidth );
       
  1360                     }
       
  1361                 
       
  1362                 if ( iRtspSock )
       
  1363                     {
       
  1364                     iRtspSock->SendData( iPrevCommands[ERTSPDescSent]->ProduceL() );
       
  1365                     StartRtspTimeout( KCRRtspResponseTimeout );
       
  1366                     iStage = ERTSPDescSent;
       
  1367                     }
       
  1368                 }
       
  1369                 break;
       
  1370             
       
  1371             case ERTSPDescSent:
       
  1372                 if ( iSdpParser )
       
  1373                     {
       
  1374                     const TInt audio( iSdpParser->MediaIdentifierAudio() );
       
  1375                     const TInt video( iSdpParser->MediaIdentifierVideo() );
       
  1376                     TBool videoExists( iSdpParser->VideoControlAddr().Length() > 0 );
       
  1377                     TBool audioExists( iSdpParser->AudioControlAddr().Length() > 0 );
       
  1378                     
       
  1379                     /* If both medias are reported with dynamic payload 
       
  1380                      * type and audio stream is reported with lower 
       
  1381                      * payload type, then some servers don't work correctly 
       
  1382                      * if the SETUP commands are not in correct order, ie.
       
  1383                      * we need to first SETUP the audio stream here.
       
  1384                      */
       
  1385                     const TBool audioBeforeVideo(
       
  1386                         audioExists && audio >= 96 && video >= 96 && audio < video );
       
  1387 
       
  1388                     if ( videoExists && !audioBeforeVideo )
       
  1389                         {
       
  1390                         SendSetupCommandL( iSdpParser->VideoControlAddr(), EFalse );
       
  1391                         iStage = ERTSPSetupVideoSent;
       
  1392                         }
       
  1393                     else if ( audioExists )
       
  1394                         {
       
  1395                         SendSetupCommandL( iSdpParser->AudioControlAddr(), ETrue );
       
  1396                         iStage = ERTSPSetupAudioSent;
       
  1397                         }
       
  1398                     else
       
  1399                         {
       
  1400                         LOG1( "CCRRtspPacketSource::SendRtspCommand stag %d have no audio nor video",
       
  1401                             ( TInt )iStage );
       
  1402                         // no audio, no video, el panique grande
       
  1403                         iOwningSession.SourceStop();
       
  1404                         }
       
  1405                     }
       
  1406                 break;
       
  1407                 
       
  1408             case ERTSPSetupAudioSent:
       
  1409                 {
       
  1410                 const TInt audio( iSdpParser->MediaIdentifierAudio() );
       
  1411                 const TInt video( iSdpParser->MediaIdentifierVideo() );
       
  1412                 
       
  1413                 if ( audio >= 96 && video >= 96 && audio < video &&
       
  1414                      iSdpParser && iSdpParser->VideoControlAddr().Length() )
       
  1415                     {
       
  1416                     // Video exists also and has not been setup before, so 
       
  1417                     // let's setup it now.
       
  1418                     
       
  1419                     TPtrC8 ctrlAddr ( iSdpParser->VideoControlAddr() );
       
  1420                     SendSetupCommandL( ctrlAddr, EFalse );
       
  1421                     iStage = ERTSPSetupVideoSent;
       
  1422                     }
       
  1423                 else
       
  1424                     {
       
  1425                     ConditionallySetupMultiCastOrTcpStreamingL();
       
  1426                     }
       
  1427                 }
       
  1428                 break;
       
  1429                 
       
  1430             case ERTSPSetupVideoSent:
       
  1431                 {
       
  1432                 const TInt audio( iSdpParser->MediaIdentifierAudio() );
       
  1433                 const TInt video( iSdpParser->MediaIdentifierVideo() );
       
  1434                 
       
  1435                 // Check explanation for this in case ERTSPDescSent above.
       
  1436                 const TBool audioBeforeVideo(
       
  1437                     audio >= 96 && video >= 96 && audio < video );
       
  1438                 
       
  1439                 // Then send audio, if applicable:
       
  1440                 if ( iSdpParser && iSdpParser->AudioControlAddr().Length() &&
       
  1441                      !audioBeforeVideo )
       
  1442                     {
       
  1443                     TPtrC8 ctrlAddr ( iSdpParser->AudioControlAddr() );
       
  1444                     SendSetupCommandL( ctrlAddr, ETrue );
       
  1445                     iStage = ERTSPSetupAudioSent;
       
  1446                     }
       
  1447                 else
       
  1448                     { 
       
  1449                     // there is no audio that need setup so lets check also multicast+tcp
       
  1450                     ConditionallySetupMultiCastOrTcpStreamingL();                  
       
  1451                     }
       
  1452                 }
       
  1453                 break;
       
  1454             
       
  1455             case ERTSPPauseSent:
       
  1456                 // If we're paused, do zero the buffer, in tcp streaming case
       
  1457                 // some servers seem to send packets even after play..
       
  1458                 break; 
       
  1459 
       
  1460             case ERTSPReadyToPlay:
       
  1461                 // In these stages send no further commands
       
  1462                 break;
       
  1463             
       
  1464             case ERTSPPlaySent:
       
  1465                 // Start timer for UDP reception and start streaming
       
  1466                 if ( iTransport == ERTPOverUDP )
       
  1467                     {
       
  1468                     iUdpReceptionTimer->Cancel();
       
  1469                     iUdpReceptionTimer->After( KCRRtspRtpUdpTimeout );
       
  1470                     }
       
  1471                 
       
  1472                 iStage = ERTSPPlaying;
       
  1473                 if ( !iNoRtpInfoHeader )
       
  1474                     {
       
  1475                     iSessionObs.StatusChanged( MCRPacketSource::ERtpStatePlaying );
       
  1476                     }
       
  1477                 break;
       
  1478             
       
  1479             case ERTSPPlaying:
       
  1480                 // None
       
  1481                 break;
       
  1482             
       
  1483             case ERTSPTearDownSent:
       
  1484                 iPostPonedPlay = EFalse; 
       
  1485                 iOwningSession.SourceStop();
       
  1486                 break;
       
  1487 
       
  1488             default:
       
  1489                 // By default send no further commands
       
  1490                 break;
       
  1491             }
       
  1492         }
       
  1493     }
       
  1494 
       
  1495 // -----------------------------------------------------------------------------
       
  1496 // CCRRtspPacketSource::SendPlayCommandL
       
  1497 // -----------------------------------------------------------------------------
       
  1498 //
       
  1499 void CCRRtspPacketSource::SendPlayCommandL(void)
       
  1500     {
       
  1501     delete iPrevCommands[ERTSPPlaySent];
       
  1502     iPrevCommands[ERTSPPlaySent] = NULL;
       
  1503     iPrevCommands[ERTSPPlaySent] = CCRRtspCommand::NewL();
       
  1504     iPrevCommands[ERTSPPlaySent]->SetCommand ( CCRRtspCommand::ERTSPCommandPLAY );
       
  1505     TPtrC8 uriDes( iRtspUri8->Des() );
       
  1506     iPrevCommands[ERTSPPlaySent]->SetURL( uriDes );
       
  1507     iPrevCommands[ERTSPPlaySent]->SetCSeq( iCSeq ++ );
       
  1508     iPrevCommands[ERTSPPlaySent]->SetRange( iStartPos , iEndPos );
       
  1509     
       
  1510     if ( iUserAgent )
       
  1511         {
       
  1512         iPrevCommands[ERTSPPlaySent]->SetUserAgentL( *iUserAgent );
       
  1513         }
       
  1514     if ( iSessionId.Ptr() )
       
  1515         {
       
  1516         iPrevCommands[ERTSPPlaySent]->SetSessionId( iSessionId );
       
  1517         }
       
  1518     if ( iAuthenticationNeeded )
       
  1519         {
       
  1520         AddAuthenticationL( ERTSPPlaySent );
       
  1521         }
       
  1522 
       
  1523     if ( iRtspSock ) 
       
  1524         {
       
  1525         iRtspSock->SendData( iPrevCommands[ERTSPPlaySent]->ProduceL() );
       
  1526         StartRtspTimeout( KCRRtspResponseTimeout );
       
  1527         iStage = ERTSPPlaySent;
       
  1528         }
       
  1529 
       
  1530     iStartPos = KRealZero;
       
  1531     iEndPos = KRealMinusOne;
       
  1532     }
       
  1533 
       
  1534 // -----------------------------------------------------------------------------
       
  1535 // CCRRtspPacketSource::SendPauseCommandL
       
  1536 // -----------------------------------------------------------------------------
       
  1537 //
       
  1538 void CCRRtspPacketSource::SendPauseCommandL(void)
       
  1539     {
       
  1540     delete iPrevCommands[ERTSPPauseSent];
       
  1541     iPrevCommands[ERTSPPauseSent] = NULL;
       
  1542     iPrevCommands[ERTSPPauseSent] = CCRRtspCommand::NewL();
       
  1543     iPrevCommands[ERTSPPauseSent]->SetCommand ( CCRRtspCommand::ERTSPCommandPAUSE );
       
  1544     TPtrC8 uriDes( iRtspUri8->Des() );
       
  1545     iPrevCommands[ERTSPPauseSent]->SetURL( uriDes );
       
  1546     iPrevCommands[ERTSPPauseSent]->SetCSeq( iCSeq ++ );
       
  1547     
       
  1548     if ( iUserAgent )
       
  1549         {
       
  1550         iPrevCommands[ERTSPPauseSent]->SetUserAgentL( *iUserAgent );
       
  1551         }
       
  1552     if ( iSessionId.Ptr() )
       
  1553         {
       
  1554         iPrevCommands[ERTSPPauseSent]->SetSessionId( iSessionId );
       
  1555         }
       
  1556     if ( iAuthenticationNeeded )
       
  1557         {
       
  1558         AddAuthenticationL( ERTSPPauseSent );
       
  1559         }
       
  1560     
       
  1561     if ( iRtspSock )
       
  1562         {
       
  1563         iRtspSock->SendData( iPrevCommands[ERTSPPauseSent]->ProduceL() );
       
  1564         StartRtspTimeout( KCRRtspResponseTimeout );
       
  1565         iStage = ERTSPPauseSent;
       
  1566         }
       
  1567     }
       
  1568 
       
  1569 // -----------------------------------------------------------------------------
       
  1570 // CCRRtspPacketSource::SendSetupCommandL
       
  1571 // -----------------------------------------------------------------------------
       
  1572 //
       
  1573 TInt CCRRtspPacketSource::SendSetupCommandL(
       
  1574     const TDesC8& aControlAddr,
       
  1575     TBool aForAudio )
       
  1576     {
       
  1577     TCRRTSPStage newStage = aForAudio ? ERTSPSetupAudioSent : ERTSPSetupVideoSent;
       
  1578 
       
  1579     delete iPrevCommands[newStage];
       
  1580     iPrevCommands[newStage] = NULL;
       
  1581     iPrevCommands[newStage] = CCRRtspCommand::NewL();
       
  1582     iPrevCommands[newStage]->SetCommand ( CCRRtspCommand::ERTSPCommandSETUP );
       
  1583     iPrevCommands[newStage]->SetURL( aControlAddr );
       
  1584     iPrevCommands[newStage]->SetCSeq( iCSeq ++ );
       
  1585     iPrevCommands[newStage]->SetTransport( iTransport );
       
  1586 
       
  1587     // Map stream to port number (when streaming over UDP) or channel (over TCP)
       
  1588     // base: iClientPort for UDP, 0 for TCP
       
  1589     // video: (base+0, base+1)
       
  1590     // audio: (base+2, base+3) or (base+0, base+1) when audio only
       
  1591     TInt portbase( ( iTransport == ERTPOverUDP )? iClientPort: 0 );
       
  1592     TInt portoffset( ( aForAudio && iSdpParser->VideoControlAddr().Length() )? 2: 0 );
       
  1593     iPrevCommands[newStage]->SetClientPort( portbase + portoffset );
       
  1594 
       
  1595     if ( iSessionId.Ptr() )
       
  1596         {
       
  1597         iPrevCommands[newStage]->SetSessionId ( iSessionId );
       
  1598         }
       
  1599     if ( iAuthenticationNeeded )
       
  1600         {
       
  1601         AddAuthenticationL( newStage );
       
  1602         }
       
  1603     if ( iUserAgent )
       
  1604         {
       
  1605         iPrevCommands[newStage]->SetUserAgentL( *iUserAgent );
       
  1606         }
       
  1607     if ( iWapProfile )
       
  1608         {
       
  1609         iPrevCommands[newStage]->SetWapProfileL( *iWapProfile );
       
  1610         }
       
  1611 
       
  1612     if ( iRtspSock ) 
       
  1613         {
       
  1614         iRtspSock->SendData( iPrevCommands[newStage]->ProduceL() );
       
  1615         StartRtspTimeout( KCRRtspResponseTimeout );
       
  1616         }
       
  1617     
       
  1618     return KErrNone;
       
  1619     }
       
  1620 
       
  1621 // -----------------------------------------------------------------------------
       
  1622 // CCRRtspPacketSource::SendTearDownCommandL
       
  1623 // -----------------------------------------------------------------------------
       
  1624 //
       
  1625 void CCRRtspPacketSource::SendTearDownCommandL()
       
  1626     {
       
  1627     CCRRtspCommand*& teardowncmd = iPrevCommands[ERTSPTearDownSent];
       
  1628     iPostPonedPlay = EFalse; 
       
  1629     if ( teardowncmd )
       
  1630         {
       
  1631         delete teardowncmd; teardowncmd = NULL;
       
  1632         }
       
  1633 
       
  1634     teardowncmd = CCRRtspCommand::NewL();
       
  1635     teardowncmd->SetCommand( CCRRtspCommand::ERTSPCommandTEARDOWN );
       
  1636     TPtrC8 uri( iRtspUri8->Des() );
       
  1637     teardowncmd->SetURL( uri );
       
  1638     teardowncmd->SetCSeq( iCSeq++ );
       
  1639 
       
  1640     if ( iSessionId.Ptr() )
       
  1641         {
       
  1642         teardowncmd->SetSessionId( iSessionId );
       
  1643         }
       
  1644     if ( iUserAgent )
       
  1645         {
       
  1646         teardowncmd->SetUserAgentL( *iUserAgent );
       
  1647         }
       
  1648     if ( iAuthenticationNeeded )
       
  1649         {
       
  1650         AddAuthenticationL( ERTSPTearDownSent );
       
  1651         }
       
  1652     
       
  1653     if ( iRtspSock )
       
  1654         {
       
  1655         iRtspSock->SendData( teardowncmd->ProduceL() );
       
  1656         }
       
  1657     }
       
  1658 
       
  1659 // -----------------------------------------------------------------------------
       
  1660 // CCRRtspPacketSource::SendOptionsCommandL
       
  1661 // -----------------------------------------------------------------------------
       
  1662 //
       
  1663 void CCRRtspPacketSource::SendOptionsCommandL(void)
       
  1664     {
       
  1665     delete iPrevCommands[ERTSPOptSent];
       
  1666     iPrevCommands[ERTSPOptSent] = NULL;
       
  1667     iPrevCommands[ERTSPOptSent] = CCRRtspCommand::NewL();
       
  1668     iPrevCommands[ERTSPOptSent]->SetCommand ( CCRRtspCommand::ERTSPCommandOPTIONS );
       
  1669     TPtrC8 uriDes ( iRtspUri8->Des() );
       
  1670     iPrevCommands[ERTSPOptSent]->SetURL ( uriDes );
       
  1671     iPrevCommands[ERTSPOptSent]->SetCSeq ( iCSeq ++ );
       
  1672     
       
  1673     if ( iUserAgent )
       
  1674         {
       
  1675         iPrevCommands[ERTSPOptSent]->SetUserAgentL( *iUserAgent );
       
  1676         }
       
  1677     if ( iSessionId.Ptr() )
       
  1678         {
       
  1679         iPrevCommands[ERTSPOptSent]->SetSessionId ( iSessionId );
       
  1680         }
       
  1681     if ( iAuthenticationNeeded )
       
  1682         {
       
  1683         AddAuthenticationL( ERTSPOptSent );
       
  1684         }
       
  1685 
       
  1686     if ( iRtspSock )
       
  1687         {
       
  1688         iRtspSock->SendData( iPrevCommands[ERTSPOptSent]->ProduceL() );
       
  1689         }
       
  1690     // Sending options ping does not change our state
       
  1691     }
       
  1692 
       
  1693 // -----------------------------------------------------------------------------
       
  1694 // CCRRtspPacketSource::SetupRTPSessions
       
  1695 // -----------------------------------------------------------------------------
       
  1696 //
       
  1697 TInt CCRRtspPacketSource::SetupRTPSessions( void )
       
  1698     {
       
  1699     TInt retval( KErrNone );
       
  1700     if ( !iRtspSock )
       
  1701         {
       
  1702         retval = KErrNotReady;
       
  1703         }
       
  1704     else
       
  1705         {
       
  1706         TInetAddr localAddr( iRtspSock->LocalAddr() );
       
  1707         TInetAddr remoteAddr( iRtspSock->ConnectedAddr() );
       
  1708         
       
  1709         // Clear used streams
       
  1710         iReceiveStreams.Reset();
       
  1711         iTrafficFound = EFalse;
       
  1712         
       
  1713         // First audio:
       
  1714         if ( iRtspSock && iResponses[ERTSPSetupAudioSent] )
       
  1715             {
       
  1716             if ( iTransport == ERTPOverMulticast )
       
  1717                 {
       
  1718                 retval = CreateMulticastSocket( ERTPAudioSend1, 
       
  1719                     iResponses[ERTSPSetupAudioSent]->Destination(),
       
  1720                     iResponses[ERTSPSetupAudioSent]->ClientPort() );
       
  1721                 if ( retval == KErrNone )
       
  1722                     {
       
  1723                     retval = CreateMulticastSocket( ERTPAudioSend2, 
       
  1724                         iResponses[ERTSPSetupAudioSent]->Destination(),
       
  1725                         iResponses[ERTSPSetupAudioSent]->ClientPort()+1 );
       
  1726                     }
       
  1727                 }
       
  1728             else
       
  1729                 {
       
  1730                 localAddr.SetPort( iResponses[ERTSPSetupAudioSent]->ClientPort() );
       
  1731                 remoteAddr.SetPort( iResponses[ERTSPSetupAudioSent]->ServerPort() );
       
  1732 
       
  1733 #if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE )
       
  1734                 TName _addr;
       
  1735                 localAddr.Output( _addr );
       
  1736                 LOG2( "localaddr for video is %S:%d", &_addr, localAddr.Port() );
       
  1737                 remoteAddr.Output( _addr );
       
  1738                 LOG2( "remoteAddr for video is %S:%d", &_addr, remoteAddr.Port() );
       
  1739 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
  1740 
       
  1741                 retval = CreateUnicastSocket( ERTPAudioSend1, localAddr, remoteAddr );
       
  1742                 if ( retval == KErrNone )
       
  1743                     {
       
  1744                     localAddr.SetPort( localAddr.Port()+1 );
       
  1745                     remoteAddr.SetPort( remoteAddr.Port()+1 );
       
  1746                     retval = CreateUnicastSocket( ERTPAudioSend2, localAddr, remoteAddr );
       
  1747                     }
       
  1748                 }
       
  1749 
       
  1750             if ( retval == KErrNone )
       
  1751                 {
       
  1752                 TRAP( retval, iAudioSession.OpenL(
       
  1753                     iRTPSockArr[ERTPAudioSend1]->Socket(),
       
  1754                     KAverageExpectedRtpPacketMaxSize,
       
  1755                     iRTPSockArr[ERTPAudioSend2]->Socket(),
       
  1756                     EPriorityNormal, KCRCName() ) );
       
  1757                 }
       
  1758 
       
  1759             LOG1( "CCRRtspPacketSource::SetupRTPSessions audio sess open: %d", retval );
       
  1760             if ( !retval )
       
  1761                 {
       
  1762                 SetRtpSession( iAudioSession , iSdpParser->AudioTimerGranularity() );
       
  1763                 iAudioSession.SetBandwidth( iSdpParser->AudioBitrate() * 1000 ); 
       
  1764                 TRAP( retval, iAudioSession.PrivRegisterEventCallbackL( ERtpNewSource, 
       
  1765                     ( TRtpCallbackFunction )CCRRtspPacketSource::AudioRTPCallBack, this ) );
       
  1766 
       
  1767                 TReceiveStream audioDataStream;
       
  1768                 audioDataStream.iStreamType = EAudioStream;
       
  1769                 audioDataStream.iDataReceived = EFalse;                
       
  1770                 iReceiveStreams.Append( audioDataStream );
       
  1771                 LOG( "CCRRtspPacketSource::SetupRTPSessions - AudioStream found" );
       
  1772                 TReceiveStream audioControlStream;
       
  1773                 audioControlStream.iStreamType = EAudioControlStream;
       
  1774                 audioControlStream.iDataReceived = EFalse;
       
  1775                 LOG( "CCRRtspPacketSource::SetupRTPSessions - AudioControlStream found" );
       
  1776                 iReceiveStreams.Append( audioControlStream );
       
  1777                 
       
  1778                 LOG2( "CCRRtspPacketSource::SetupRTPSessions audio stat: %d, ts: %u",
       
  1779                     retval, ( TUint )iRTPTimeStampAudio );
       
  1780                 }
       
  1781             else
       
  1782                 {
       
  1783                 if ( iObserver )
       
  1784                     {
       
  1785                     iObserver->ConnectionStatusChange(
       
  1786                         iOwningSession.SourceChecksum(),
       
  1787                         ECRConnectionError, retval );
       
  1788                     }
       
  1789                 iOwningSession.SourceStop();                    
       
  1790                 }
       
  1791             }
       
  1792 
       
  1793         // Then video
       
  1794         if ( retval == KErrNone && iRtspSock && iResponses[ERTSPSetupVideoSent] )
       
  1795             {
       
  1796             if ( iTransport==ERTPOverMulticast )
       
  1797                 {
       
  1798                 retval = CreateMulticastSocket( ERTPVideoSend1, 
       
  1799                     iResponses[ERTSPSetupVideoSent]->Destination(),
       
  1800                     iResponses[ERTSPSetupVideoSent]->ClientPort() );
       
  1801                 if ( retval==KErrNone )
       
  1802                     {
       
  1803                     retval = CreateMulticastSocket( ERTPVideoSend2, 
       
  1804                         iResponses[ERTSPSetupVideoSent]->Destination(),
       
  1805                         iResponses[ERTSPSetupVideoSent]->ClientPort()+1 );
       
  1806                     }
       
  1807                 }
       
  1808             else
       
  1809                 {
       
  1810                 localAddr.SetPort( iResponses[ERTSPSetupVideoSent]->ClientPort() );
       
  1811                 remoteAddr.SetPort( iResponses[ERTSPSetupVideoSent]->ServerPort() );
       
  1812 
       
  1813 #if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE )
       
  1814                 TName _addr;
       
  1815                 localAddr.Output( _addr );
       
  1816                 LOG2( "localaddr for video is %S:%d", &_addr, localAddr.Port() );
       
  1817                 remoteAddr.Output( _addr );
       
  1818                 LOG2( "remoteAddr for video is %S:%d", &_addr, remoteAddr.Port() );
       
  1819 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
  1820 
       
  1821                 retval = CreateUnicastSocket( ERTPVideoSend1, localAddr, remoteAddr );
       
  1822                 if ( retval == KErrNone )
       
  1823                     {
       
  1824                     localAddr.SetPort( localAddr.Port() + 1 );
       
  1825                     remoteAddr.SetPort( remoteAddr.Port() + 1 );
       
  1826                     retval = CreateUnicastSocket( ERTPVideoSend2, localAddr, remoteAddr );
       
  1827                     }
       
  1828                 }
       
  1829 
       
  1830             if ( retval == KErrNone )
       
  1831                 {
       
  1832                 TRAP( retval, iVideoSession.OpenL( iRTPSockArr[ERTPVideoSend1]->Socket(),
       
  1833                     KAverageExpectedRtpPacketMaxSize, iRTPSockArr[ERTPVideoSend2]->Socket(),
       
  1834                     EPriorityNormal, KCRCName() ) );
       
  1835                 }
       
  1836 
       
  1837             LOG1( "CCRRtspPacketSource::SetupRTPSessions video sess open: %d", retval );
       
  1838             if ( !retval )
       
  1839                 {
       
  1840                 SetRtpSession( iVideoSession , iSdpParser->VideoTimerGranularity() );
       
  1841                 iVideoSession.SetBandwidth( iSdpParser->VideoBitrate() * 1000 ); 
       
  1842                 TRAP( retval, iVideoSession.PrivRegisterEventCallbackL( ERtpNewSource,
       
  1843                     ( TRtpCallbackFunction )CCRRtspPacketSource::VideoRTPCallBack, this ) );
       
  1844 
       
  1845                 TReceiveStream videoDataStream;
       
  1846                 videoDataStream.iStreamType = EVideoStream;
       
  1847                 videoDataStream.iDataReceived = EFalse;
       
  1848                 LOG( "CCRRtspPacketSource::SetupRTPSessions - VideoStream found" );
       
  1849                 iReceiveStreams.Append( videoDataStream );
       
  1850                 TReceiveStream videoControlStream;
       
  1851                 videoControlStream.iStreamType = EVideoControlStream;
       
  1852                 videoControlStream.iDataReceived = EFalse;
       
  1853                 LOG( "CCRRtspPacketSource::SetupRTPSessions - VideoControlStream found" );
       
  1854                 iReceiveStreams.Append( videoControlStream );
       
  1855                     
       
  1856                 LOG2( "CCRRtspPacketSource::SetupRTPSessions video stat: %d, ts: %u",
       
  1857                     retval, ( TUint )iRTPTimeStampVideo );
       
  1858                 }
       
  1859             else
       
  1860                 {
       
  1861                 if ( iObserver )
       
  1862                     {
       
  1863                     iObserver->ConnectionStatusChange(
       
  1864                         iOwningSession.SourceChecksum(),
       
  1865                         ECRConnectionError, retval );
       
  1866                     }
       
  1867                 iOwningSession.SourceStop();                    
       
  1868                 }
       
  1869             }
       
  1870         }
       
  1871     
       
  1872     return retval;
       
  1873     }
       
  1874 
       
  1875 // -----------------------------------------------------------------------------
       
  1876 // CCRRtspPacketSource::CreateMulticastSocket
       
  1877 // -----------------------------------------------------------------------------
       
  1878 //
       
  1879 TInt CCRRtspPacketSource::CreateMulticastSocket(
       
  1880     TCRRTPSockId aSockId, 
       
  1881     const TInetAddr& aGroupAddr,
       
  1882     TInt aPort )
       
  1883     {
       
  1884     // Alias for socket being created
       
  1885     CCRSock*& sock = iRTPSockArr[aSockId];
       
  1886 
       
  1887     // Delete if already existing
       
  1888     if ( sock )
       
  1889         {
       
  1890         delete sock;
       
  1891         sock = NULL;
       
  1892         }
       
  1893 
       
  1894     // Create socket
       
  1895     TRAPD( err, sock = CCRSock::NewL( *this, aSockId, iConnection.Connection(),
       
  1896                                       iSockServer, EFalse, EFalse) );
       
  1897     if ( err != KErrNone )
       
  1898         {
       
  1899         LOG2( "CCRRtspPacketSource::CreateMulticastSocket: CCRSock::NewL FAILED, sockId: %d, err: %d",
       
  1900             aSockId, err );
       
  1901         return err;
       
  1902         }
       
  1903 
       
  1904     // Bind socket to local UDP port, issue no reads -> handled by RRtpSession
       
  1905     err = sock->ListenPort( aPort );
       
  1906     if ( err != KErrNone )
       
  1907         {
       
  1908         LOG2( "CCRRtspPacketSource::CreateMulticastSocket: ListenPort FAILED, port: %d, err: %d",
       
  1909             aPort, err );
       
  1910         return err;
       
  1911         }
       
  1912 
       
  1913     err = sock->JoinGroup( aGroupAddr );
       
  1914     if ( err != KErrNone )
       
  1915         {
       
  1916         LOG1( "CCRRtspPacketSource::CreateMulticastSocket: JoinGroup FAILED, err: %d", err );
       
  1917         return err;
       
  1918         }
       
  1919 
       
  1920 #if defined(LIVE_TV_FILE_TRACE) || defined(LIVE_TV_RDEBUG_TRACE)
       
  1921     TName group;
       
  1922     aGroupAddr.Output( group );
       
  1923     LOG3( "CCRRtspPacketSource::CreateMulticastSocket: sockid: %d, group: '%S', port: %d OK",
       
  1924         aSockId, &group, aPort );
       
  1925 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
  1926 
       
  1927     return KErrNone;
       
  1928     }
       
  1929 
       
  1930 // -----------------------------------------------------------------------------
       
  1931 // CCRRtspPacketSource::CreateUnicastSocket
       
  1932 // -----------------------------------------------------------------------------
       
  1933 TInt CCRRtspPacketSource::CreateUnicastSocket(
       
  1934     TCRRTPSockId aSockId, 
       
  1935     const TInetAddr& aLocalAddr,
       
  1936     const TInetAddr& /*aRemoteAddr*/ )
       
  1937     {
       
  1938     // Alias for socket being created
       
  1939     CCRSock*& sock = iRTPSockArr[aSockId];
       
  1940 
       
  1941     // Delete if already existing
       
  1942     if ( sock )
       
  1943         {
       
  1944         delete sock;
       
  1945         sock = NULL;
       
  1946         }
       
  1947 
       
  1948     // Create socket: EFalse=UDP, EFalse=issue no read (handled by RRtpSession)
       
  1949     TRAPD( err, sock = CCRSock::NewL( *this,aSockId, iConnection.Connection(),
       
  1950                                       iSockServer, EFalse, EFalse ) );
       
  1951     if ( err != KErrNone )
       
  1952         {
       
  1953         LOG2( "CCRRtspPacketSource::CreateUnicastSocket: CCRSock::NewL FAILED, sockId: %d, err: %d",
       
  1954             aSockId, err );
       
  1955         return err;
       
  1956         }
       
  1957 
       
  1958     // Bind to local port, ignore remote address and port
       
  1959     TInt port = aLocalAddr.Port();
       
  1960     err = sock->ListenPort( port );
       
  1961     if ( err != KErrNone )
       
  1962         {
       
  1963         LOG2( "CCRRtspPacketSource::CreateUnicastSocket: ListenPort FAILED, port: %d, err: %d",
       
  1964             port, err );
       
  1965         return err;
       
  1966         }
       
  1967 
       
  1968 #if defined(LIVE_TV_FILE_TRACE) || defined(LIVE_TV_RDEBUG_TRACE)
       
  1969     LOG2( "CCRRtspPacketSource::CreateUnicastSocket: sockid: %d, port: %d OK",
       
  1970         aSockId, port );
       
  1971 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
  1972 
       
  1973     return KErrNone;
       
  1974     }
       
  1975 
       
  1976 // -----------------------------------------------------------------------------
       
  1977 // CCRRtspPacketSource::RTPPayloadProcessor
       
  1978 // This is called from audio and video callbacks when real payload packet
       
  1979 // is received from rtp stack.
       
  1980 // -----------------------------------------------------------------------------
       
  1981 //
       
  1982 void CCRRtspPacketSource::RTPPayloadProcessor(
       
  1983     const TRtpEvent& aEvent,
       
  1984     const TBool aIsAudio )
       
  1985     {
       
  1986     // If udp traffic hasn't been flagged as found
       
  1987     // keep marking streams as found
       
  1988     if ( !iTrafficFound )
       
  1989         {            
       
  1990         if ( aIsAudio )
       
  1991             {
       
  1992             StreamFound( EAudioStream );        
       
  1993             }
       
  1994         else
       
  1995             {
       
  1996             StreamFound( EVideoStream );        
       
  1997             }
       
  1998 
       
  1999         // Cancel UDP timer, so as not to trigger TCP streaming
       
  2000         if ( CheckReceiveOfStreams() )
       
  2001             {
       
  2002             // We have traffic from all needed streams, cancel reception timer
       
  2003             // and set UDP flag.            
       
  2004             iUdpReceptionTimer->Cancel();
       
  2005             iUdpFound = ETrue;
       
  2006             iTrafficFound = ETrue;
       
  2007             }
       
  2008         }    
       
  2009 
       
  2010     // Here process packet
       
  2011     RRtpReceivePacket p = aEvent.ReceiveSource().Packet();
       
  2012     TUint32 flag( 0 );
       
  2013     BigEndian::Put32( ( TUint8* )&flag, p.Flags() );
       
  2014 
       
  2015     // Header
       
  2016     TCRRtpMessageHeader packetHeader;
       
  2017     memcpy( &packetHeader, &flag, sizeof( flag ) );
       
  2018     BigEndian::Put32( ( TUint8* )&packetHeader.iTimestamp, p.Timestamp() );
       
  2019     BigEndian::Put32( ( TUint8* )&packetHeader.iSSRC, p.SSRC() );
       
  2020     TPtrC8 rtpHeader( ( TUint8* )&packetHeader, sizeof( packetHeader ) );
       
  2021 
       
  2022     if ( iNoRtpInfoHeader )
       
  2023         {
       
  2024         ConstructSeqAndTsForSink(
       
  2025             aIsAudio ? MCRPacketSource::EAudioStream : MCRPacketSource::EVideoStream,
       
  2026             0 /*nop*/, 0 /*nop*/, 0 /*nop*/, p.SequenceNumber() );
       
  2027         }
       
  2028 
       
  2029     // Stream
       
  2030     MCRPacketSource::TCRPacketStreamId stream( 
       
  2031         ( aIsAudio )? MCRPacketSource::EAudioStream : 
       
  2032                       MCRPacketSource::EVideoStream );
       
  2033     iBuffer->AddPacket( stream, rtpHeader, p.Payload() );
       
  2034     
       
  2035     // Count of packets
       
  2036     if ( aIsAudio )
       
  2037         {
       
  2038         iAudioBytes += p.Payload( ).Length();
       
  2039         iAudioPackets ++;
       
  2040         }
       
  2041     else
       
  2042         {
       
  2043         iVideoBytes += p.Payload( ).Length();
       
  2044         iVideoPackets ++;
       
  2045         }
       
  2046 
       
  2047     p.Close();
       
  2048     }
       
  2049 
       
  2050 // -----------------------------------------------------------------------------
       
  2051 // CCRRtspPacketSource::AudioRTPCallBack
       
  2052 // -----------------------------------------------------------------------------
       
  2053 //
       
  2054 void CCRRtspPacketSource::AudioRTPCallBack(
       
  2055     CCRRtspPacketSource* aPtr,
       
  2056     const TRtpEvent& aEvent )
       
  2057     {
       
  2058     switch ( aEvent.Type() )
       
  2059         {
       
  2060         case ERtpPacketReceived:
       
  2061             static_cast<CCRRtspPacketSource*>( aPtr )->
       
  2062                 RTPPayloadProcessor( aEvent, ETrue );
       
  2063             break;
       
  2064 
       
  2065         // RTCP
       
  2066         case ERtpSR:
       
  2067             {
       
  2068             // We have audio control traffic
       
  2069             if ( !aPtr->iTrafficFound )
       
  2070                 {                    
       
  2071                 aPtr->StreamFound( EAudioControlStream );
       
  2072                 if ( aPtr->CheckReceiveOfStreams() )
       
  2073                     {                    
       
  2074                     // Cancel UDP timer, so as not to trigger TCP streaming
       
  2075                     aPtr->iUdpReceptionTimer->Cancel();
       
  2076                     aPtr->iUdpFound = ETrue;
       
  2077                     aPtr->iTrafficFound = ETrue;
       
  2078                     }
       
  2079                 }
       
  2080 
       
  2081             // Sender report
       
  2082             SenderReport( aPtr, aEvent, MCRPacketSource::EAudioControlStream );
       
  2083             }
       
  2084             break;
       
  2085 
       
  2086         case ERtpNewSource:
       
  2087             {
       
  2088             // Handle audio 
       
  2089             TRAPD( err, HandleNewSourceL( aPtr, aPtr->iRtpRecvSrcAudio, aEvent,
       
  2090                 ( TRtpCallbackFunction )CCRRtspPacketSource::AudioRTPCallBack ) );
       
  2091             if ( err )
       
  2092                 {
       
  2093                 LOG1( "CCRRtspPacketSource::AudioRTPCallBack(), HandleNewSourceL Leaved: %d", err );
       
  2094                 aPtr->iOwningSession.SourceStop();
       
  2095                 }
       
  2096             }
       
  2097             break;
       
  2098 
       
  2099         case ERtpSessionFail:
       
  2100         case ERtpSourceFail:
       
  2101             LOG( "CCRRtspPacketSource::VideoRTPCallBack(), source/session fail" );
       
  2102             aPtr->iOwningSession.SourceStop();
       
  2103             if ( aPtr->iObserver )
       
  2104                 {
       
  2105                 aPtr->iObserver->ConnectionStatusChange( 
       
  2106                      aPtr->iOwningSession.SourceChecksum(),
       
  2107                      ECRNormalEndOfStream, KErrSessionClosed );
       
  2108                 }
       
  2109             break;
       
  2110 
       
  2111         case ERtpBYE:
       
  2112             LOG( "CCRRtspPacketSource::AudioRTPCallBack(), ERtpBYE" );
       
  2113             if ( aPtr->iObserver )
       
  2114                 {
       
  2115                 aPtr->iObserver->ConnectionStatusChange( 
       
  2116                      aPtr->iOwningSession.SourceChecksum(), 
       
  2117                      ECRNormalEndOfStream, KErrNone );
       
  2118                 }
       
  2119             break;
       
  2120         
       
  2121         default:
       
  2122             LOG1( "CCRRtspPacketSource::AudioRTPCallBack default case, type 0x%x",
       
  2123                 ( TUint )( aEvent.Type() ) );
       
  2124             // by do nothing
       
  2125             break;
       
  2126         }
       
  2127     }
       
  2128 
       
  2129 // -----------------------------------------------------------------------------
       
  2130 // CCRRtspPacketSource::VideoRTPCallBack
       
  2131 // -----------------------------------------------------------------------------
       
  2132 //
       
  2133 void CCRRtspPacketSource::VideoRTPCallBack(
       
  2134     CCRRtspPacketSource* aPtr,
       
  2135     const TRtpEvent& aEvent )
       
  2136     {
       
  2137     switch ( aEvent.Type() )
       
  2138         {
       
  2139         case ERtpPacketReceived:
       
  2140             static_cast<CCRRtspPacketSource*>( aPtr )->
       
  2141                 RTPPayloadProcessor( aEvent, EFalse );
       
  2142             break;
       
  2143 
       
  2144         // RTCP
       
  2145         case ERtpSR:
       
  2146             {
       
  2147             // We have video control traffic
       
  2148             if ( !aPtr->iTrafficFound )
       
  2149                 {                    
       
  2150                 aPtr->StreamFound( EVideoControlStream );
       
  2151                 if ( aPtr->CheckReceiveOfStreams() )
       
  2152                     {                    
       
  2153                     // Cancel UDP timer, so as not to trigger TCP streaming
       
  2154                     aPtr->iUdpReceptionTimer->Cancel();
       
  2155                     aPtr->iUdpFound = ETrue;
       
  2156                     aPtr->iTrafficFound = ETrue;
       
  2157                     }
       
  2158                 }
       
  2159 
       
  2160             // Sender report
       
  2161             SenderReport( aPtr, aEvent, MCRPacketSource::EVideoControlStream );
       
  2162             }
       
  2163             break;
       
  2164 
       
  2165         case ERtpNewSource:
       
  2166             {
       
  2167             // Handle video
       
  2168             TRAPD( err, HandleNewSourceL( aPtr, aPtr->iRtpRecvSrcVideo, aEvent,
       
  2169                 ( TRtpCallbackFunction )CCRRtspPacketSource::VideoRTPCallBack ) );
       
  2170             if ( err )
       
  2171                 {
       
  2172                 LOG1( "CCRRtspPacketSource::VideoRTPCallBack(), HandleNewSourceL Leaved: %d", err );
       
  2173                 aPtr->iOwningSession.SourceStop();
       
  2174                 }
       
  2175             }
       
  2176             break;
       
  2177         
       
  2178         case ERtpSessionFail:
       
  2179         case ERtpSourceFail:
       
  2180             LOG( "CCRRtspPacketSource::VideoRTPCallBack(), Source/session fail" );
       
  2181             aPtr->iOwningSession.SourceStop();
       
  2182             if ( aPtr->iObserver )
       
  2183                 {
       
  2184                 aPtr->iObserver->ConnectionStatusChange( 
       
  2185                      aPtr->iOwningSession.SourceChecksum(),
       
  2186                      ECRNormalEndOfStream, KErrSessionClosed );
       
  2187                 }
       
  2188             break;
       
  2189 
       
  2190         case ERtpBYE:
       
  2191             LOG( "CCRRtspPacketSource::VideoRTPCallBack(), ERtpBYE" );
       
  2192             if ( aPtr->iObserver )
       
  2193                 {
       
  2194                 aPtr->iObserver->ConnectionStatusChange( 
       
  2195                      aPtr->iOwningSession.SourceChecksum(), 
       
  2196                      ECRNormalEndOfStream, KErrNone );
       
  2197                 }
       
  2198             break;
       
  2199 
       
  2200         default:
       
  2201             LOG1( "CCRRtspPacketSource::VideoRTPCallBack default case, type 0x%x",
       
  2202                 ( TUint )( aEvent.Type() ) );
       
  2203             // By do nothing
       
  2204             break;
       
  2205         }
       
  2206     }
       
  2207 
       
  2208 // -----------------------------------------------------------------------------
       
  2209 // CCRRtspPacketSource::SenderReport
       
  2210 // rfc-1305:
       
  2211 // NTP timestamps are represented as a 64-bit unsigned fixed-
       
  2212 // point number, in seconds relative to 0h on 1 January 1900.
       
  2213 // The integer part is in the first 32 bits and the fraction
       
  2214 // part in the last 32 bits.
       
  2215 // -----------------------------------------------------------------------------
       
  2216 //
       
  2217 void CCRRtspPacketSource::SenderReport(
       
  2218     CCRRtspPacketSource* aPtr,
       
  2219     const TRtpEvent& aEvent,
       
  2220     MCRPacketSource::TCRPacketStreamId aStreamId )
       
  2221     {
       
  2222     TCRRtpSRReportHeader srReport;
       
  2223     srReport.iVersion = KRtpPacketVersion; // value is 2
       
  2224     srReport.iPadding = 0;
       
  2225     srReport.iReportCount = 0;
       
  2226     srReport.iPacketType = KSenderReportPacketType;
       
  2227     RRtpReceiveSource source( aEvent.ReceiveSource() );
       
  2228     BigEndian::Put16( ( TUint8* )&srReport.iLength, 6 );
       
  2229     BigEndian::Put32( ( TUint8* )&srReport.iSenderSSRC,
       
  2230         source.SSRC() );
       
  2231     BigEndian::Put32( ( TUint8* )&srReport.iMSWTimestamp,
       
  2232         source.GetSR().iSrPtr.ntp_sec );
       
  2233     BigEndian::Put32( ( TUint8* )&srReport.iLSWTimestamp,
       
  2234         source.GetSR().iSrPtr.ntp_frac );
       
  2235     BigEndian::Put32( ( TUint8* )&srReport.iRTPTimestamp, 
       
  2236         source.GetSR().RTPTimestamp() );
       
  2237     BigEndian::Put32( ( TUint8* )&srReport.iSenderPacketCount,
       
  2238         aPtr->iAudioPackets );
       
  2239     BigEndian::Put32( ( TUint8* )&srReport.iSenderOctetCount,
       
  2240         aPtr->iAudioBytes );
       
  2241     TPtrC8 rtcpHeader( ( TUint8* )&srReport, sizeof( srReport ) );
       
  2242     aPtr->iBuffer->AddPacket( aStreamId, rtcpHeader );
       
  2243 
       
  2244     // Verify Seq and Ts 
       
  2245     if ( aPtr->iNoRtpInfoHeader )
       
  2246         {
       
  2247         aPtr->ConstructSeqAndTsForSink (
       
  2248             aStreamId,
       
  2249             source.GetSR().iSrPtr.ntp_sec,
       
  2250             source.GetSR().iSrPtr.ntp_frac,
       
  2251             source.GetSR().RTPTimestamp(),
       
  2252             0 ); // 0 not used
       
  2253         }
       
  2254     }
       
  2255 
       
  2256 // -----------------------------------------------------------------------------
       
  2257 // CCRRtspPacketSource::HandleNewSourceL
       
  2258 // -----------------------------------------------------------------------------
       
  2259 //
       
  2260 void CCRRtspPacketSource::HandleNewSourceL(
       
  2261     CCRRtspPacketSource* aPtr,
       
  2262     RRtpReceiveSource& aSource,
       
  2263     const TRtpEvent& aEvent,
       
  2264     TRtpCallbackFunction aCallback )
       
  2265     {
       
  2266     // Cancel UDP timer, so as not to trigger TCP streaming
       
  2267     aPtr->iUdpReceptionTimer->Cancel();
       
  2268     delete aPtr->iPunchPacketSenderAudio;
       
  2269     aPtr->iPunchPacketSenderAudio = NULL;
       
  2270     if ( aSource.IsOpen() )
       
  2271         {
       
  2272         aSource.Close();
       
  2273         }
       
  2274 
       
  2275     // Source
       
  2276     aSource = aEvent.Session().NewReceiveSourceL();
       
  2277     aSource.PrivRegisterEventCallbackL( ERtpPacketReceived, aCallback, aPtr );
       
  2278     aSource.PrivRegisterEventCallbackL( ERtpSR, aCallback, aPtr );
       
  2279     aSource.PrivRegisterEventCallbackL( ERtpBYE, aCallback, aPtr );
       
  2280     aSource.PrivRegisterEventCallbackL( ERtpSessionFail, aCallback, aPtr );
       
  2281     aSource.PrivRegisterEventCallbackL( ERtpSourceFail, aCallback, aPtr );
       
  2282     
       
  2283     // Ping Timer
       
  2284     if ( !aPtr->iRtspPingTimer )
       
  2285         {
       
  2286         aPtr->iRtspPingTimer = CPeriodic::NewL( CActive::EPriorityLow );
       
  2287         aPtr->iRtspPingTimer->Start(
       
  2288             KDVR10Seconds, 2 * KDVR10Seconds, TCallBack( SendRtspPing, aPtr ) );
       
  2289         }
       
  2290 
       
  2291     aEvent.Session().SendAPPL( KCRCName() );
       
  2292     aEvent.Session().SetRTCPAutoSend( ETrue );
       
  2293     }
       
  2294     
       
  2295 // -----------------------------------------------------------------------------
       
  2296 // CCRRtspPacketSource::SendAuthDescribeL
       
  2297 // -----------------------------------------------------------------------------
       
  2298 //
       
  2299 void CCRRtspPacketSource::SendAuthDescribeL( )
       
  2300     {
       
  2301     delete iPrevCommands[ERTSPDescSent];
       
  2302     iPrevCommands[ERTSPDescSent] = NULL;
       
  2303     iPrevCommands[ERTSPDescSent] = CCRRtspCommand::NewL();
       
  2304     iPrevCommands[ERTSPDescSent]->SetCommand (
       
  2305         CCRRtspCommand::ERTSPCommandDESCRIBE );
       
  2306     TPtrC8 uriDes ( iRtspUri8->Des() );
       
  2307     iPrevCommands[ERTSPDescSent]->SetURL ( uriDes );
       
  2308     iPrevCommands[ERTSPDescSent]->SetCSeq ( iCSeq ++ );
       
  2309     
       
  2310     if ( iAuthType )
       
  2311         {
       
  2312         iPrevCommands[ERTSPDescSent]->SetAuthenticationTypeL( iAuthType->Des() );
       
  2313         }
       
  2314     if ( iNonce )
       
  2315         {
       
  2316         iPrevCommands[ERTSPDescSent]->SetNonceL( iNonce->Des() );
       
  2317         }
       
  2318     if ( iRealm )
       
  2319         {
       
  2320         iPrevCommands[ERTSPDescSent]->SetRealmL( iRealm->Des() );
       
  2321         }
       
  2322     if ( iOpaque )
       
  2323         {
       
  2324         iPrevCommands[ERTSPDescSent]->SetOpaqueL( iOpaque->Des() );
       
  2325         }
       
  2326     if ( iUserAgent )
       
  2327         {
       
  2328         iPrevCommands[ERTSPDescSent]->SetUserAgentL( *iUserAgent );
       
  2329         }
       
  2330     if ( iWapProfile )
       
  2331         {
       
  2332         iPrevCommands[ERTSPDescSent]->SetWapProfileL( *iWapProfile );
       
  2333         }
       
  2334     if ( iBandwidth )
       
  2335         {
       
  2336         iPrevCommands[ERTSPDescSent]->SetBandwidth( iBandwidth );
       
  2337         }
       
  2338     
       
  2339     iPrevCommands[ERTSPDescSent]->SetUserNameL( iUserName->Des() );
       
  2340     iPrevCommands[ERTSPDescSent]->SetPassWdL( iPassword->Des() );
       
  2341     iPrevCommands[ERTSPDescSent]->SetRtspUriL( iRtspUri->Des() );
       
  2342     iPrevCommands[ERTSPDescSent]->SetAuthentication ( iAuthenticationNeeded );
       
  2343     if ( iRtspSock ) 
       
  2344         {
       
  2345         iRtspSock->SendData( iPrevCommands[ERTSPDescSent]->ProduceL() );
       
  2346         StartRtspTimeout( KCRRtspResponseTimeout );
       
  2347         }
       
  2348     iStage = ERTSPDescSent;
       
  2349     }
       
  2350 
       
  2351 // -----------------------------------------------------------------------------
       
  2352 // CCRRtspPacketSource::AddAuthenticationL
       
  2353 // -----------------------------------------------------------------------------
       
  2354 //
       
  2355 void CCRRtspPacketSource::AddAuthenticationL( TInt aCommand )
       
  2356     {
       
  2357     if ( iPrevCommands[aCommand] && iNonce && 
       
  2358          iOpaque && iUserName && iPassword )
       
  2359         {
       
  2360         iPrevCommands[aCommand]->SetAuthenticationTypeL( iAuthType->Des() );
       
  2361         iPrevCommands[aCommand]->SetNonceL( iNonce->Des() );
       
  2362         iPrevCommands[aCommand]->SetRealmL( iRealm->Des() );
       
  2363         iPrevCommands[aCommand]->SetOpaqueL( iOpaque->Des() );
       
  2364         iPrevCommands[aCommand]->SetUserNameL( iUserName->Des() );
       
  2365         iPrevCommands[aCommand]->SetPassWdL( iPassword->Des() );
       
  2366         iPrevCommands[aCommand]->SetRtspUriL( iRtspUri->Des() );
       
  2367         iPrevCommands[aCommand]->SetAuthentication ( iAuthenticationNeeded );
       
  2368         }
       
  2369     }
       
  2370 
       
  2371 // -----------------------------------------------------------------------------
       
  2372 // CCRRtspPacketSource::PunchPacketsSent
       
  2373 // -----------------------------------------------------------------------------
       
  2374 //
       
  2375 void CCRRtspPacketSource::PunchPacketsSent( CCRPunchPacketSender* aPuncher )
       
  2376     {
       
  2377     if ( iPunchPacketSenderVideo && aPuncher == iPunchPacketSenderVideo )
       
  2378         {
       
  2379         iPunchPacketSentForVideo = ETrue;
       
  2380         }
       
  2381     if ( iPunchPacketSenderAudio && aPuncher == iPunchPacketSenderAudio )
       
  2382         {
       
  2383         iPunchPacketSentForAudio = ETrue;
       
  2384         }
       
  2385     if ( ( iPunchPacketSenderVideo && !iPunchPacketSenderAudio && 
       
  2386            iPunchPacketSentForVideo ) ||
       
  2387          ( !iPunchPacketSenderVideo && iPunchPacketSenderAudio &&
       
  2388            iPunchPacketSentForAudio ) ||
       
  2389          ( iPunchPacketSenderVideo && iPunchPacketSenderAudio && 
       
  2390            iPunchPacketSentForVideo && iPunchPacketSentForAudio ) )
       
  2391         {
       
  2392         LOG1( "PunchPacketsSent, play readiness: %d", iReadyToPlay );
       
  2393         SetupSessionsAndPlay();
       
  2394         }
       
  2395     }
       
  2396 
       
  2397 // -----------------------------------------------------------------------------
       
  2398 // CCRRtspPacketSource::SetupSessionsAndPlay
       
  2399 // -----------------------------------------------------------------------------
       
  2400 //
       
  2401 void CCRRtspPacketSource::SetupSessionsAndPlay()
       
  2402     {
       
  2403     // all needed punch packets are sent:
       
  2404     if ( SetupRTPSessions() != KErrNone )
       
  2405         {
       
  2406         iOwningSession.SourceStop();
       
  2407         }
       
  2408     else
       
  2409         {
       
  2410         // if we're ready to play, play
       
  2411         if ( iReadyToPlay )
       
  2412             {
       
  2413             TRAPD( err, SendPlayCommandL() );
       
  2414             if ( err != KErrNone )
       
  2415                 {
       
  2416                 iOwningSession.SourceStop();
       
  2417                 }
       
  2418             }
       
  2419         else
       
  2420             {
       
  2421             iStage = ERTSPReadyToPlay;
       
  2422             }
       
  2423         }
       
  2424     }
       
  2425 
       
  2426 // -----------------------------------------------------------------------------
       
  2427 // CCRRtspPacketSource::SendPunchPackets
       
  2428 // -----------------------------------------------------------------------------
       
  2429 //
       
  2430 void CCRRtspPacketSource::SendPunchPacketsL( void )
       
  2431     {
       
  2432     LOG( "CCRRtspPacketSource::SendPunchPacketsL in" );
       
  2433     delete iPunchPacketSenderAudio;
       
  2434     iPunchPacketSenderAudio = NULL;
       
  2435     delete iPunchPacketSenderVideo;
       
  2436     iPunchPacketSenderVideo = NULL;
       
  2437 
       
  2438     if ( iSdpParser &&iRtspSock && iResponses[ERTSPSetupVideoSent] )
       
  2439         {
       
  2440         TInetAddr localAddr = iRtspSock->LocalAddr();
       
  2441         TInetAddr remoteAddr = iRtspSock->ConnectedAddr();
       
  2442         localAddr.SetPort(iResponses[ERTSPSetupVideoSent]->ClientPort());
       
  2443         remoteAddr.SetPort(iResponses[ERTSPSetupVideoSent]->ServerPort());
       
  2444         iPunchPacketSenderVideo = CCRPunchPacketSender::NewL(
       
  2445             iConnection.Connection(), iSockServer,
       
  2446             localAddr, remoteAddr, 0, *this );
       
  2447         }
       
  2448     if ( iSdpParser && iRtspSock && iResponses[ERTSPSetupAudioSent] )
       
  2449         {
       
  2450         TInetAddr localAddr = iRtspSock->LocalAddr();
       
  2451         TInetAddr remoteAddr = iRtspSock->ConnectedAddr();
       
  2452         localAddr.SetPort(iResponses[ERTSPSetupAudioSent]->ClientPort());
       
  2453         remoteAddr.SetPort(iResponses[ERTSPSetupAudioSent]->ServerPort());
       
  2454         iPunchPacketSenderAudio = CCRPunchPacketSender::NewL(
       
  2455             iConnection.Connection(), iSockServer,
       
  2456             localAddr, remoteAddr, 0, *this );
       
  2457         }
       
  2458     }
       
  2459 
       
  2460 // -----------------------------------------------------------------------------
       
  2461 // CCRRtspPacketSource::ConnectionStatusChange
       
  2462 // -----------------------------------------------------------------------------
       
  2463 //
       
  2464 void CCRRtspPacketSource::ConnectionStatusChange(
       
  2465     TInt /*aSessionId*/,
       
  2466     TCRConnectionStatus aStatus,
       
  2467     TInt /* aErr */ )
       
  2468     {
       
  2469     switch( aStatus )
       
  2470         {
       
  2471         // Connection has gone up or bearer has changed -> check bandwidth
       
  2472         case ECRBearerChanged:
       
  2473             {
       
  2474             LOG( "CCRRtspPacketSource::ConnectionStatusChange: IapUp or IapUp2G" );
       
  2475             if ( iSdpParser && iObserver )
       
  2476                 {
       
  2477                 // Unknown bitrate or bandwidth are returned as zero. Bitrates in kbit/s
       
  2478                 TInt bitrate( iSdpParser->VideoBitrate() + 
       
  2479                               iSdpParser->AudioBitrate() );
       
  2480                 TInt bandwidth( iConnection.MaximumBandwidth() / 1000 );
       
  2481                 if ( bitrate > 0 && bandwidth > 0 && bandwidth < bitrate )
       
  2482                     {
       
  2483                     LOG2( "CCRRtspPacketSource::ConnectionStatusChange: clip_bitrate: %d, connection_bandwidth: %d -> NotEnoughBandwidth",
       
  2484                         bitrate, bandwidth );
       
  2485                     iObserver->ConnectionStatusChange(
       
  2486                         iOwningSession.SourceChecksum(), ECRNotEnoughBandwidth, KErrNone );
       
  2487                     }
       
  2488                 }
       
  2489             break;
       
  2490             }
       
  2491 
       
  2492         // Connection has gone down or error occured -> switch back to RTP/UDP transport
       
  2493         case ECRConnectionError:
       
  2494         case ECRIapDown:
       
  2495             {
       
  2496             LOG( "CCRRtspPacketSource::ConnectionStatusChange: IapDown or ConnectionError -> switch to RTP/UDP streaming" );
       
  2497             iConnection.SetHeuristic( CCRConnection::EUdpStreamingBlocked, EFalse );
       
  2498             break;
       
  2499             }
       
  2500 
       
  2501         // Nothing to do for:
       
  2502         // ECRConnecting
       
  2503         // ECRAuthenticationNeeded
       
  2504         // ECRNotEnoughBandwidth
       
  2505         // ECRNormalEndOfStream
       
  2506         default:
       
  2507             {
       
  2508             LOG1( "CCRRtspPacketSource::ConnectionStatusChange: unhandled status: %d", aStatus );
       
  2509             break;
       
  2510             }
       
  2511         }
       
  2512     }
       
  2513 
       
  2514 // -----------------------------------------------------------------------------
       
  2515 // CCRRtspPacketSource::RegisterConnectionObs
       
  2516 // -----------------------------------------------------------------------------
       
  2517 //
       
  2518 void CCRRtspPacketSource::RegisterConnectionObs( MCRConnectionObserver* aObserver )
       
  2519     {
       
  2520     iObserver = aObserver;
       
  2521     }
       
  2522 
       
  2523 // -----------------------------------------------------------------------------
       
  2524 // CCRRtspPacketSource::UnregisterConnectionObs
       
  2525 // -----------------------------------------------------------------------------
       
  2526 //
       
  2527 void CCRRtspPacketSource::UnregisterConnectionObs( )
       
  2528     {
       
  2529     iObserver = NULL;
       
  2530     }
       
  2531 
       
  2532 // -----------------------------------------------------------------------------
       
  2533 // CCRRtspPacketSource::SetRtpSession
       
  2534 // -----------------------------------------------------------------------------
       
  2535 //
       
  2536 void CCRRtspPacketSource::SetRtpSession(
       
  2537     RRtpSession& aSession,
       
  2538     TReal aGranularity )
       
  2539     {
       
  2540     // Unit is 1/second
       
  2541     __ASSERT_DEBUG( iSdpParser != NULL, User::Panic( _L( "RTSP source" ), KErrBadHandle ) );
       
  2542     TUint32 howManyNanoSecondsIsOneTick( 
       
  2543         ( TUint32 )( TReal( 1000000000.0L ) / aGranularity ) );
       
  2544     LOG1( "CCRRtspPacketSource::SetRtpSession clock tick: %u", howManyNanoSecondsIsOneTick );        
       
  2545     aSession.SetRTPTimeConversion( 0, howManyNanoSecondsIsOneTick );
       
  2546     aSession.SetRtpStreamParameters( KDVRMinSequential, // 1
       
  2547                                      KDVRMaxMisorder,   // 50
       
  2548                                      KDVRMaxDropOut );  // 3000
       
  2549     }
       
  2550 
       
  2551 // -----------------------------------------------------------------------------
       
  2552 // CCRRtspPacketSource::SendRtspPing
       
  2553 // -----------------------------------------------------------------------------
       
  2554 //
       
  2555 TInt CCRRtspPacketSource::SendRtspPing( TAny* aSelfPtr )
       
  2556     {
       
  2557     CCRRtspPacketSource* ptr = static_cast<CCRRtspPacketSource*> ( aSelfPtr );
       
  2558     TRAPD( err, ptr->SendOptionsCommandL() );
       
  2559     return err;
       
  2560     }
       
  2561 
       
  2562 // -----------------------------------------------------------------------------
       
  2563 // CCRRtspPacketSource::ConstructSeqAndTsForSink
       
  2564 // -----------------------------------------------------------------------------
       
  2565 //
       
  2566 void CCRRtspPacketSource::ConstructSeqAndTsForSink ( 
       
  2567     MCRPacketSource::TCRPacketStreamId aStreamId,
       
  2568     TUint32 aMSWTimestamp,
       
  2569     TUint32 aLSWTimestamp,
       
  2570     TUint32 aRTPTimestamp,
       
  2571     TUint aSeq ) 
       
  2572     {
       
  2573     switch ( aStreamId )
       
  2574         {
       
  2575         case EAudioStream:
       
  2576             if ( iRTPTimeStampAudio )
       
  2577                 {
       
  2578                 iSeqFromRtpInfoForAudio = aSeq;
       
  2579                 if ( iSeqFromRtpInfoForAudio == 0 )
       
  2580                     {
       
  2581                     iSeqFromRtpInfoForAudio++;
       
  2582                     }
       
  2583                 LOG1( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Audio seq: %d ", ( int )aSeq );  
       
  2584                 // We may declare that we have seq+ts if we're here and have only audio or
       
  2585                 // if we're here and have both audio and video and have also seq for video
       
  2586                 if ( ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrAudioOnly )  ||
       
  2587                      ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrBothAudioAndVideo &&
       
  2588                        iSeqFromRtpInfoForVideo && iRTPTimeStampVideo ) )
       
  2589                     {
       
  2590                     iSessionObs.StatusChanged( 
       
  2591                         MCRPacketSource::ERtpStateSeqAndTSAvailable );                   
       
  2592                     iNoRtpInfoHeader = EFalse;  
       
  2593                     if ( iStage == ERTSPPlaying )
       
  2594                         {
       
  2595                         iSessionObs.StatusChanged( 
       
  2596                             MCRPacketSource::ERtpStatePlaying );                                            
       
  2597                         }
       
  2598                     }
       
  2599                 }
       
  2600             break;
       
  2601         
       
  2602         case EAudioControlStream:
       
  2603             if ( !iMSWTimestamp ) 
       
  2604                 { // no wall clock time yet set
       
  2605                 iMSWTimestamp = aMSWTimestamp; 
       
  2606                 iLSWTimestamp = aLSWTimestamp; 
       
  2607                 iRTPTimeStampAudio = aRTPTimestamp; 
       
  2608                 if ( iRTPTimeStampAudio == 0 ) 
       
  2609                     {
       
  2610                     iRTPTimeStampAudio++; 
       
  2611                     }
       
  2612                 }
       
  2613             else
       
  2614                 { 
       
  2615                 // Sync audio with video
       
  2616                 TInt64 wallClockOfVideo = MAKE_TINT64 ( iMSWTimestamp , iLSWTimestamp ); 
       
  2617                 TInt64 wallClockOfAudio = MAKE_TINT64 ( aMSWTimestamp , aLSWTimestamp ); 
       
  2618                 // Then figure out the difference. unit is now difficult ; upper 
       
  2619                 // 32 bits contain whole seconds, lower contains fraction
       
  2620                 TInt64 wallClockDifference( wallClockOfVideo - wallClockOfAudio );
       
  2621                 // Now, the aRTPTimestamp has different scale, declared in SDP. 
       
  2622                 // first make one second that has same scale as wallClockDifference
       
  2623                 TInt64 granularity( MAKE_TINT64( 1, 0 ) ); 
       
  2624                 // Then divide that one second with the given granularity. variable
       
  2625                 // granularity will now contain in its low 32 bits the fraction of the
       
  2626                 // second that re-presents one clock tick (e.g. 1/90000 sec for video)
       
  2627                 granularity = granularity / static_cast<TInt64>(
       
  2628                     iSdpParser->AudioTimerGranularity() ); 
       
  2629                 // Then divide our difference with this fraction of second
       
  2630                 TInt64 wallClockDifferenceGranular = wallClockDifference / granularity;
       
  2631                 // unit of wallClockDifferenceGranular is now 2^32 / granularity             
       
  2632                 TInt32 wallClockDifferenceGranular32 = wallClockDifferenceGranular;
       
  2633                 LOG2( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Audio ts: %u adjust by: %d",
       
  2634                     aRTPTimestamp , wallClockDifferenceGranular32 );        
       
  2635                 iRTPTimeStampAudio = aRTPTimestamp + wallClockDifferenceGranular32;                
       
  2636                 if ( iRTPTimeStampAudio == 0 ) 
       
  2637                     {
       
  2638                     iRTPTimeStampAudio++; 
       
  2639                     }
       
  2640                 }
       
  2641             break;                         
       
  2642         
       
  2643         case EVideoStream:
       
  2644             if ( iRTPTimeStampVideo )
       
  2645                 {
       
  2646                 iSeqFromRtpInfoForVideo = aSeq;
       
  2647                 if ( iSeqFromRtpInfoForVideo == 0 )
       
  2648                     {
       
  2649                     iSeqFromRtpInfoForVideo++;
       
  2650                     }
       
  2651                 LOG1( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Video seq: %d ",
       
  2652                     ( int )aSeq );        
       
  2653 
       
  2654                 // We may declare that we have seq+ts if we're here and have only video or
       
  2655                 // if we're here and have both and have also seq for video
       
  2656                 if ( ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrVideoOnly )  ||
       
  2657                      ( iSdpParser->SupportedContent() == CDvrSdpParser::EDvrBothAudioAndVideo &&
       
  2658                        iSeqFromRtpInfoForAudio && iRTPTimeStampAudio ) )
       
  2659                     {
       
  2660                     iSessionObs.StatusChanged( 
       
  2661                         MCRPacketSource::ERtpStateSeqAndTSAvailable );                   
       
  2662                     iNoRtpInfoHeader = EFalse;  
       
  2663                     if ( iStage == ERTSPPlaying )
       
  2664                         {
       
  2665                         iSessionObs.StatusChanged( 
       
  2666                             MCRPacketSource::ERtpStatePlaying );                                            
       
  2667                         }
       
  2668                     }
       
  2669                 }
       
  2670             break;                         
       
  2671         
       
  2672         case EVideoControlStream:
       
  2673             if ( !iMSWTimestamp ) 
       
  2674                 { // No wall clock time yet set
       
  2675                 iMSWTimestamp = aMSWTimestamp; 
       
  2676                 iLSWTimestamp = aLSWTimestamp; 
       
  2677                 iRTPTimeStampVideo = aRTPTimestamp; 
       
  2678                 if ( iRTPTimeStampVideo == 0 ) 
       
  2679                     {
       
  2680                     iRTPTimeStampVideo++; 
       
  2681                     }               
       
  2682                 }
       
  2683             else
       
  2684                 { 
       
  2685                 // Sync audio with video
       
  2686                 TInt64 wallClockOfAudio = MAKE_TINT64 ( iMSWTimestamp , iLSWTimestamp ); 
       
  2687                 TInt64 wallClockOfVideo = MAKE_TINT64 ( aMSWTimestamp , aLSWTimestamp ); 
       
  2688                 // Then figure out the difference. unit is now difficult ; upper 
       
  2689                 // 32 bits contain whole seconds, lower contains fraction
       
  2690                 TInt64 wallClockDifference( wallClockOfAudio - wallClockOfVideo );
       
  2691                 // Now, the aRTPTimestamp has different scale, declared in SDP. 
       
  2692                 // first make one second that has same scale as wallClockDifference
       
  2693                 TInt64 granularity( MAKE_TINT64( 1, 0 ) ); 
       
  2694                 // Then divide that one second with the given granularity. variable
       
  2695                 // granularity will now contain in its low 32 bits the fraction of the
       
  2696                 // second that re-presents one clock tick (e.g. 1/90000 sec for video)
       
  2697                 granularity = granularity / static_cast<TInt64>(
       
  2698                     iSdpParser->VideoTimerGranularity()); 
       
  2699                 // Then divide our difference with this fraction of second
       
  2700                 TInt64 wallClockDifferenceGranular = wallClockDifference / granularity;
       
  2701                 // Unit of wallClockDifferenceGranular is now 2^32 / granularity             
       
  2702                 TInt32 wallClockDifferenceGranular32 = wallClockDifferenceGranular;
       
  2703                 LOG2( "CCRRtspPacketSource::ConstructSeqAndTsForSink(), Video ts: %u adjust by: %d",
       
  2704                     aRTPTimestamp , wallClockDifferenceGranular32 );        
       
  2705                 iRTPTimeStampVideo = aRTPTimestamp + wallClockDifferenceGranular32;
       
  2706                 if ( iRTPTimeStampVideo == 0 ) 
       
  2707                     {
       
  2708                     iRTPTimeStampVideo++; 
       
  2709                     }               
       
  2710                 }
       
  2711             break;
       
  2712         
       
  2713         default:
       
  2714             // no thing
       
  2715             break;
       
  2716         }
       
  2717     }
       
  2718 
       
  2719 // -----------------------------------------------------------------------------
       
  2720 // CCRRtspPacketSource::ConditionallySetupMultiCastOrTcpStreamingL
       
  2721 // -----------------------------------------------------------------------------
       
  2722 //
       
  2723 void CCRRtspPacketSource::ConditionallySetupMultiCastOrTcpStreamingL ( void ) 
       
  2724     {
       
  2725     // UDP: Punch packets or play sent in ProcessRTSPResponseL, so do nothing.
       
  2726     if ( iTransport == ERTPOverUDP )
       
  2727         { 
       
  2728         }
       
  2729     // Multicast: no punch packets needed but session setup yes
       
  2730     else if ( iTransport == ERTPOverMulticast )
       
  2731         {
       
  2732         SetupSessionsAndPlay();
       
  2733         }
       
  2734     
       
  2735     // TCP: no punch packets or session, just send PLAY .. but wait for UI
       
  2736     else if ( iTransport == ERTPOverTCP  )
       
  2737         {
       
  2738         if ( iReadyToPlay )
       
  2739             {
       
  2740             SendPlayCommandL();
       
  2741             }
       
  2742         else
       
  2743             {
       
  2744             iStage = ERTSPReadyToPlay;
       
  2745             }
       
  2746         }
       
  2747     }
       
  2748 
       
  2749 // -----------------------------------------------------------------------------
       
  2750 // CCRRtspPacketSource::CheckReceiveOfStreams
       
  2751 // -----------------------------------------------------------------------------
       
  2752 //
       
  2753 TBool CCRRtspPacketSource::CheckReceiveOfStreams()
       
  2754     {
       
  2755     TBool retVal( ETrue );
       
  2756     
       
  2757     // Go through all streams and check that all streams have receive flag on,
       
  2758     // if not return false.
       
  2759     for ( TInt i = 0 ; i < iReceiveStreams.Count() ; i++ )
       
  2760         {
       
  2761         if ( iReceiveStreams[i].iDataReceived == EFalse )
       
  2762             {
       
  2763             LOG1( "CCRRtspPacketSource::CheckReceiveOfStreams - Missing atleast stream %d", iReceiveStreams[i].iStreamType );
       
  2764             retVal = EFalse;
       
  2765             break;
       
  2766             }        
       
  2767         }
       
  2768         
       
  2769     if ( retVal )
       
  2770         {
       
  2771         LOG( "CCRRtspPacketSource::CheckReceiveOfStreams - Receiving from all streams!" );
       
  2772         }
       
  2773         
       
  2774     return retVal;    
       
  2775     }
       
  2776     
       
  2777 // -----------------------------------------------------------------------------
       
  2778 // CCRRtspPacketSource::StreamFound
       
  2779 // -----------------------------------------------------------------------------
       
  2780 //
       
  2781 void CCRRtspPacketSource::StreamFound( TCRPacketStreamId aStreamType )
       
  2782     {
       
  2783      // Go through streams and find correct stream to set the receive flag.
       
  2784     for ( TInt i = 0 ; i < iReceiveStreams.Count(); i++ )
       
  2785         {
       
  2786         if ( iReceiveStreams[i].iStreamType == aStreamType )
       
  2787             {
       
  2788             iReceiveStreams[i].iDataReceived = ETrue;
       
  2789             LOG1( "CCRRtspPacketSource::StreamFound - Stream %d found", iReceiveStreams[i].iStreamType );            
       
  2790             break;
       
  2791             }
       
  2792         }
       
  2793     }
       
  2794     
       
  2795 // -----------------------------------------------------------------------------
       
  2796 // CCRRtspPacketSource::ResetStreamFlags
       
  2797 // -----------------------------------------------------------------------------
       
  2798 //
       
  2799 void CCRRtspPacketSource::ResetStreamFlags( )
       
  2800     {
       
  2801      // Go through streams and clear receiving flag.
       
  2802     for ( TInt i = 0 ; i < iReceiveStreams.Count() ; i++ )
       
  2803         {        
       
  2804         iReceiveStreams[i].iDataReceived = EFalse;         
       
  2805         }
       
  2806         
       
  2807     // We have to check receive again    
       
  2808     iTrafficFound = EFalse;
       
  2809     }    
       
  2810     
       
  2811 #if defined ( LIVE_TV_FILE_TRACE ) || defined ( LIVE_TV_RDEBUG_TRACE )
       
  2812 // -----------------------------------------------------------------------------
       
  2813 // CCRRtspPacketSource::ShowHeader
       
  2814 // -----------------------------------------------------------------------------
       
  2815 //
       
  2816 void CCRRtspPacketSource::ShowHeader(
       
  2817     const TDesC8& aRtcpHeader,
       
  2818     const TCRRtpSRReportHeader& aSrReport )
       
  2819     {
       
  2820     TBuf<100> b( KNullDesC );
       
  2821     LOG1( "CCRRtspPacketSource::TCP control packet len: %d", aRtcpHeader.Length() );
       
  2822     for ( TInt j( 0 ); j < 32 && j < aRtcpHeader.Length(); j++ )
       
  2823         {
       
  2824         b.AppendFormat( _L( "%2X " ), ( unsigned )( aRtcpHeader[j] ) );
       
  2825         if ( j > 0 && ( ( j % 16 ) == 0 ) )
       
  2826             {
       
  2827             LOG2( "%d -> %S", j, &b );
       
  2828             b.Zero();
       
  2829             }
       
  2830         }
       
  2831 
       
  2832     LOG1( "iVersion %u", ( unsigned )aSrReport.iVersion  );
       
  2833     LOG1( "iPadding %u", ( unsigned )aSrReport.iPadding );
       
  2834     LOG1( "iReportCount %u",( unsigned )aSrReport.iReportCount );
       
  2835     LOG1( "iPacketType %u", ( unsigned )aSrReport.iPacketType );
       
  2836     LOG1( "iLength %u",
       
  2837         ( unsigned)BigEndian::Get16( ( const TUint8* )&aSrReport.iLength ) );
       
  2838     LOG1( "iSenderSSRC %u",
       
  2839         ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iSenderSSRC ) );
       
  2840     LOG1( "iMSWTimestamp %u",
       
  2841         ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iMSWTimestamp) );
       
  2842     LOG1( "iLSWTimestamp %u",
       
  2843         ( unsigned)BigEndian::Get32( ( const TUint8* )&aSrReport.iLSWTimestamp ) );
       
  2844     LOG1( "iRTPTimestamp %u",
       
  2845         ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iRTPTimestamp ) );
       
  2846     LOG1( "iSenderPacketCount %u",
       
  2847         ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iSenderPacketCount) );
       
  2848     LOG1( "iSenderOctetCount %u",
       
  2849         ( unsigned )BigEndian::Get32( ( const TUint8* )&aSrReport.iSenderOctetCount ) );
       
  2850         
       
  2851     }
       
  2852 #endif // LIVE_TV_FILE_TRACE || LIVE_TV_RDEBUG_TRACE
       
  2853 
       
  2854 //  End of File