diff -r 798ee5f1972c -r 826cea16efd9 dvrengine/CommonRecordingEngine/src/CCRRTSPResponse.cpp --- a/dvrengine/CommonRecordingEngine/src/CCRRTSPResponse.cpp Thu Aug 19 10:54:18 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( 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