--- a/dvrengine/CommonRecordingEngine/src/CCRRTSPResponse.cpp Fri Jun 11 10:05:41 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,510 +0,0 @@
-/*
-* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: RTSP response parser and producer*
-*/
-
-
-
-
-// INCLUDE FILES
-#include "CCRRtspResponse.h"
-#include "CRRTSPCommon.h"
-#include "videoserviceutilsLogger.h"
-
-// CONSTANTS
-const TInt KDVRMinRTSPResponseLen( 14 );
-
-// ============================ MEMBER FUNCTIONS ===============================
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::CCRRtspResponse
-// C++ default constructor can NOT contain any code, that might leave.
-// -----------------------------------------------------------------------------
-//
-CCRRtspResponse::CCRRtspResponse()
- : iStatusCode( ERTSPRespContinue ),
- iServerPort( KErrNotFound ),
- iSSRC( NULL, 0 )
- {
- // None
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::NewL
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-//
-CCRRtspResponse* CCRRtspResponse::NewL()
- {
- CCRRtspResponse* self = new( ELeave ) CCRRtspResponse();
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop( self );
- return self;
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::ConstructL
-// Symbian 2nd phase constructor can leave.
-// -----------------------------------------------------------------------------
-//
-void CCRRtspResponse::ConstructL()
- {
- // None
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::~CCRRtspResponse
-// Destructor.
-// -----------------------------------------------------------------------------
-//
-CCRRtspResponse::~CCRRtspResponse()
- {
- LOG( "CCRRtspResponse::~CCRRtspResponse" );
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::TryParseL
-//
-// -----------------------------------------------------------------------------
-//
-void CCRRtspResponse::TryParseL( const TDesC8 &aString )
- {
- if ( aString.Length() < KDVRMinRTSPResponseLen )
- {
- LOG( "CCRRtspResponse::TryParseL(), Length less than minimum, Leaved: KErrUnderflow" );
- User::Leave( KErrUnderflow );
- }
-
- // Copy the stuff into local variable:
- delete iRtspText; iRtspText = NULL;
- iRtspText = aString.AllocL();
-
- const TInt KReplyHeaderOffset( KCRRTSPReplyHeader().Length() );
- const TInt KStatusNumberLen( 5 );
-
- // Try to find out if end of the command has been received
- // "RTSP/1.0 XXX\r\n\r\n" at least..
- TInt replyEndOffSet = aString.FindC( KCR2NewLines() );
- if ( replyEndOffSet == KErrNotFound )
- {
- // Need to have more, do nothing yet.. except that some servers
- // do not append 2 newlines to 404 or other error responses:
- if ( !aString.Left( KReplyHeaderOffset ).CompareC( KCRRTSPReplyHeader() ) )
- {
- TPtrC8 statusNumberString(
- aString.Mid( KReplyHeaderOffset, KStatusNumberLen ) );
- TLex8 statusNumberLex( statusNumberString );
- TInt statusCodeInteger( KErrNotFound );
- User::LeaveIfError ( statusNumberLex.Val( statusCodeInteger ) ) ;
- iStatusCode = static_cast<TResponseCode>( statusCodeInteger );
- if ( iStatusCode != ERTSPRespOK &&
- iStatusCode != ERTSPRespCreated &&
- iStatusCode != ERTSPRespProxyAuthenticationRequired &&
- iStatusCode != ERTSPRespUnauthorized )
- {
- // Was something else than ok or unauthorized-401
- FindCSeqL();
- LOG1( "CCRRtspResponse::TryParseL() out, with rtsp error code: %d", iStatusCode );
- return;
- }
- }
-
- LOG( "CCRRtspResponse::TryParseL() out, because response not complete" );
- User::Leave( KErrUnderflow );
- }
-
- LOG1( "CCRRtspResponse::TryParseL(), replyEndOffSet: %d", replyEndOffSet );
-
- // Find status code:
- if ( iRtspText->Left( KReplyHeaderOffset ).CompareC( KCRRTSPReplyHeader() ) == 0 )
- {
- TPtrC8 statusNumberString( iRtspText->Mid(
- KReplyHeaderOffset, KStatusNumberLen ) );
- TLex8 statusNumberLex( statusNumberString );
- TInt statusCodeInteger( KErrNotFound );
- User::LeaveIfError ( statusNumberLex.Val( statusCodeInteger ) );
- iStatusCode = ( TResponseCode )( statusCodeInteger );
- }
- else
- {
- LOG( "CCRRtspResponse::TryParseL(), Statuscode integer not found !" );
- User::Leave( KErrNotSupported );
- }
-
- LOG1( "CCRRtspResponse::TryParseL(), iStatusCode: %d", iStatusCode );
-
- FindContentL();
- // Then find CSeq
- FindCSeqL();
- // Then find session id
- FindSessionIdL();
- // Then find server ports
- FindServerPorts();
- // Then find SSRC
- FindSSRC();
- // Then try finding rtp-info header if it was play reply
- FindRTPInfoHeader();
- // Find possible transport method
- // IMPORTANT: should be done before parsing client port
- FindTransport();
- // Find possible client port
- FindClientPorts();
- if ( iServerPort == KErrNotFound && iClientPort != KErrNotFound )
- {
- LOG( "CCRRtspResponse::TryParseL(), using client port as server port -> UGLY!!" );
- iServerPort = iClientPort ;
- }
- // Find destination address is existing
- FindDestination();
- // Try finding authentication
- FindRTPAuthenticationL();
- // Try to find range header
- ParseRange();
- // Try to find session-base header
- FindContentBase();
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::StatusCode
-//
-// -----------------------------------------------------------------------------
-//
-CCRRtspResponse::TResponseCode CCRRtspResponse::StatusCode( void )
- {
- return iStatusCode;
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::FindServerPorts
-//
-// method that finds server port numeric value
-// -----------------------------------------------------------------------------
-//
-void CCRRtspResponse::FindServerPorts( void )
- {
- iServerPort = KErrNotFound;
- TInt portNumberOffset( iRtspText->FindC( KCRServerPort ) );
- if ( portNumberOffset != KErrNotFound )
- {
- const TInt KDVRPortNumberMaxLen ( 5 ) ;
- TPtrC8 portNumberStr( iRtspText->Mid(
- portNumberOffset + KCRServerPort().Length() + 1, KDVRPortNumberMaxLen ) );
- TLex8 portNumberLex( portNumberStr );
- if ( portNumberLex.Val( iServerPort ) != KErrNone )
- { // something wrong?
- LOG( "CCRRtspResponse::FindServerPorts(), portNumberLex.Val() != KErrNone" );
- iServerPort = KErrNotFound;
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::ServerPort
-//
-// method that returns server port numeric value
-// -----------------------------------------------------------------------------
-//
-TInt CCRRtspResponse::ServerPort( void )
- {
- return iServerPort;
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::FindSSRC
-//
-// -----------------------------------------------------------------------------
-//
-void CCRRtspResponse::FindSSRC( void )
- {
- LOG( "CCRRtspResponse::FindSSRC() in" );
- TInt SSRCOffset( KErrNotFound );
- iSSRC.Set( NULL, 0 );
-
- if ( ( SSRCOffset = iRtspText->FindC( KCRSSRC ) ) != KErrNotFound )
- {
- TPtrC8 SSRCStr( iRtspText->Right(
- ( iRtspText->Length() - SSRCOffset ) - 6 ) );
- TInt SSRCLen( 0 );
- for ( TInt i( 0 ); i < SSRCStr.Length(); i++ )
- {
- if ( TChar( SSRCStr[i] ).IsAlphaDigit() )
- {
- SSRCLen++;
- }
- else
- {
- iSSRC.Set( SSRCStr.Mid( 0, SSRCLen ) );
- }
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::SSRC
-//
-// method that returns SSRC string
-// -----------------------------------------------------------------------------
-//
-TInt CCRRtspResponse::SSRC( TPtrC8& aSSRC )
- {
- if ( iSSRC.Ptr() != NULL )
- {
- aSSRC.Set( iSSRC );
- return KErrNone;
- }
- else
- {
- return KErrNotFound;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::FindRTPInfoHeader
-//
-// method that partially parses rtp info header
-// -----------------------------------------------------------------------------
-//
-void CCRRtspResponse::FindRTPInfoHeader( void )
- {
- TInt offset = iRtspText->FindC( KCRRtpInfo ); // "Rtp-Info: "
- TInt url2OffSet( KErrNotFound );
-
- iRTPInfoHeader.iFirstURL.Set( NULL , 0 );
- iRTPInfoHeader.iFirstSeq = 0;
- iRTPInfoHeader.iFirstTS = 0;
- iRTPInfoHeader.iSecondURL.Set( NULL, 0 );
- iRTPInfoHeader.iSecondSeq = 0;
- iRTPInfoHeader.iSecondTS = 0;
-
- if ( offset > 0 )
- {
- // Yes, there is header. That seems to be sucky to parse. We have delimiting
- // characters ,; and nl and we may or may not find words url, seq and rtptime
- // and maybe something else. We may be confident that there will be at max
- // 2 url srings
- offset += KCRRtpInfo().Length(); // add the len of "RTP-Info: "
- TPtrC8 rtpInfoContent = iRtspText->Right( iRtspText->Length() - offset );
- TInt urlOffSet = rtpInfoContent.FindC( KCRUrlStr );
-
- for ( TInt i( 0 ); urlOffSet != KErrNotFound && i < 2; i ++ )
- {
- // At least one url string found
- TPtrC8 urlContent( iRtspText->Right( iRtspText->Length() -
- ( offset + urlOffSet + 4 ) ) );
- // Above string now contains rest of the PLAY commands RTSP OK response
- // so in practice there is 2 url-strings. If so, find the next one
- // and cut our string
- if ( ( url2OffSet = urlContent.FindC( KCRUrlStr ) ) > 0 )
- {
- urlContent.Set( urlContent.Left( url2OffSet ) );
- }
-
- // Ok, now there is only one url string in urlContent.
- // then just find seq and ts
- TInt seqOffSet = urlContent.FindC( KCRSeqStr );
- if ( seqOffSet != KErrNotFound )
- {
- TPtrC8 seqContent( urlContent.Right( urlContent.Length() -
- ( seqOffSet + KCRSeqStr().Length() ) ) );
- TLex8 seqLex( seqContent );
- if ( seqLex.Val( ( iRTPInfoHeader.iFirstURL.Length() == 0 )?
- iRTPInfoHeader.iFirstSeq : iRTPInfoHeader.iSecondSeq,
- EDecimal ) == KErrNone )
- {
- TInt tsOffSet( urlContent.FindC( KCRRtptimeStr ) );
- if ( tsOffSet != KErrNotFound )
- {
- TPtrC8 tsContent( urlContent.Right( urlContent.Length() -
- ( tsOffSet + KCRRtptimeStr().Length() ) ) );
- TLex8 tsLex( tsContent );
- tsLex.Val( ( iRTPInfoHeader.iFirstURL.Length() == 0 )?
- iRTPInfoHeader.iFirstTS:
- iRTPInfoHeader.iSecondTS, EDecimal );
- }
- }
- else
- {
- urlContent.Set ( NULL , 0 ) ;
- }
- }
- else
- {
- urlContent.Set ( NULL , 0 ) ;
- }
-
- if ( urlContent.Length() > 0 )
- {
- TInt semicolonOffSet( urlContent.Locate(';') );
- const TInt KDVRMinSemicolonOffset ( 5 ) ;
- if ( iRTPInfoHeader.iFirstURL.Length() == 0 && semicolonOffSet > KDVRMinSemicolonOffset )
- {
- iRTPInfoHeader.iFirstURL.Set(
- urlContent.Mid( 0, semicolonOffSet ) );
- }
- else
- {
- const TInt KDVRURLBeginOffset ( 4 ) ;
- iRTPInfoHeader.iSecondURL.Set(
- urlContent.Mid( KDVRURLBeginOffset,
- semicolonOffSet - KDVRURLBeginOffset ) );
- }
- }
-
- // Then continue with next url
- urlOffSet = url2OffSet;
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::RTPInfoHeader
-//
-// method that returns rtp-info header content
-// -----------------------------------------------------------------------------
-//
-TInt CCRRtspResponse::RTPInfoHeader(
- CCRRtspResponse::SRTPInfoHeader &aRTPInfoHeader )
- {
- if ( iRTPInfoHeader.iFirstURL.Length() == 0 )
- {
- return KErrNotFound;
- }
- else
- {
- aRTPInfoHeader.iFirstURL.Set( iRTPInfoHeader.iFirstURL );
- aRTPInfoHeader.iFirstSeq = iRTPInfoHeader.iFirstSeq;
- aRTPInfoHeader.iFirstTS = iRTPInfoHeader.iFirstTS;
- aRTPInfoHeader.iSecondURL.Set( iRTPInfoHeader.iSecondURL );
- aRTPInfoHeader.iSecondSeq = iRTPInfoHeader.iSecondSeq;
- aRTPInfoHeader.iSecondTS = iRTPInfoHeader.iSecondTS;
-
- return KErrNone;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCRRtspResponse::FindRTPAuthenticationL
-//
-// method that partially parses rtp authentication header
-// -----------------------------------------------------------------------------
-//
-void CCRRtspResponse::FindRTPAuthenticationL( void )
- {
- TInt endPos( KErrNotFound );
-
- // First look for authorization method(basic / digest)
- TInt pos = iRtspText->FindC( KCRAuthDigest );
-
- // digest
- if ( pos != KErrNotFound )
- {
- // Digest found, we can continue
- LOG( "CCRRtspResponse::FindRTPAuthenticationL() Digest found" );
-
- delete iAuthType;
- iAuthType = NULL;
- iAuthType = HBufC8::NewL( KCRAuthDigest().Length() );
- iAuthType->Des().Copy( KCRAuthDigest );
-
- // find "realm"
- pos = iRtspText->FindC( KCRAuthRealm );
- if ( pos != KErrNotFound )
- {
- LOG( "CCRRtspResponse::FindRTPAuthenticationL() realm found" );
- pos = pos + KCRAuthRealm().Length(); // realm
- endPos = iRtspText->Mid( pos ).LocateF( '"' );
-
- if ( endPos != KErrNotFound )
- {
- TPtrC8 data = iRtspText->Mid( pos ).Left( endPos );
- delete iRealm;
- iRealm = NULL;
- iRealm = HBufC8::NewL( data.Length() );
- iRealm->Des().Copy( data );
- }
- }
-
- // Find "nonce"
- pos = iRtspText->FindC( KCRAuthNonce() );
- if ( pos != KErrNotFound )
- {
- LOG( "CCRRtspResponse::FindRTPAuthenticationL() nonce found" );
- pos = pos + KCRAuthNonce().Length(); // nonce
- endPos = iRtspText->Mid( pos ).LocateF( '"' );
- if ( endPos != KErrNotFound )
- {
- TPtrC8 nonceData = iRtspText->Mid( pos ).Left( endPos );
- delete iNonce;
- iNonce = NULL;
- iNonce = HBufC8::NewL( nonceData.Length() );
- iNonce->Des().Copy( nonceData );
- }
- }
-
- // Find "opaque"(it seems that Darwin streaming server does not send this one)
- pos = iRtspText->FindC( KCRAuthOpaque() );
- if ( pos != KErrNotFound )
- {
- LOG( "CCRRtspResponse::FindRTPAuthenticationL() opaque found" );
- pos = pos + KCRAuthOpaque().Length(); // opaque
- endPos = iRtspText->Mid( pos ).LocateF( '"' );
- if ( endPos != KErrNotFound )
- {
- TPtrC8 opaqData = iRtspText->Mid( pos ).Left( endPos );
- delete iOpaque;
- iOpaque = NULL;
- iOpaque = HBufC8::NewL( opaqData.Length() );
- iOpaque->Des().Copy( opaqData );
- }
- }
- }
-
- // basic
- else
- {
- pos = iRtspText->FindC( KCRAuthBasic );
-
- if ( pos != KErrNotFound )
- {
- LOG( "CCRRtspResponse::FindRTPAuthenticationL() Basic found" );
-
- delete iAuthType;
- iAuthType = NULL;
- iAuthType = HBufC8::NewL( KCRAuthBasic().Length() );
- iAuthType->Des().Copy( KCRAuthBasic );
-
- // find "realm"
- pos = iRtspText->FindC( KCRAuthRealm );
-
- if ( pos != KErrNotFound )
- {
- LOG( "CCRRtspResponse::FindRTPAuthenticationL() realm found" );
- pos = pos + KCRAuthRealm().Length(); // realm
- endPos = iRtspText->Mid( pos ).LocateF( '"' );
-
- if ( endPos != KErrNotFound )
- {
- TPtrC8 data = iRtspText->Mid( pos ).Left( endPos );
- delete iRealm;
- iRealm = NULL;
- iRealm = HBufC8::NewL( data.Length() );
- iRealm->Des().Copy( data );
- }
- }
- }
- }
- }
-
-// End of File