diff -r 000000000000 -r 09774dfdd46b internetradio2.0/dataprovidersrc/irdataprovider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internetradio2.0/dataprovidersrc/irdataprovider.cpp Mon Apr 19 14:01:53 2010 +0300 @@ -0,0 +1,433 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: ?Description +* +*/ + + +#include "irdataprovider.h" +#include "irdataproviderobserver.h" +#include "irdebug.h" +#include "irhttpdataprovider.h" +#include "irhttprequestdata.h" +#include "irsettings.h" + +// --------------------------------------------------------------------------- +// CIRDataProvider::NewL(MIRDataProviderObserver& aObserver) +// Creates instance of CIRDataProvider. +// --------------------------------------------------------------------------- +// +EXPORT_C CIRDataProvider *CIRDataProvider::NewL( + MIRDataProviderObserver &aObserver ) + { + IRLOG_DEBUG( "CIRDataProvider::NewL - Entering" ); + CIRDataProvider *self = NewLC( aObserver ); + CleanupStack::Pop(self); + IRLOG_DEBUG( "CIRDataProvider::NewL - Exiting" ); + return self; + } + +// --------------------------------------------------------------------------- +// CIRDataProvider::NewL(MIRDataProviderObserver& aObserver) +// Creates instance of CIRDataProvider. +// --------------------------------------------------------------------------- +// +EXPORT_C CIRDataProvider *CIRDataProvider::NewL( + MIRDataProviderObserver &aObserver, const TDesC &aFileName ) + { + IRLOG_DEBUG( "CIRDataProvider::NewL(..., &aFileName) - Entering" ); + CIRDataProvider *self = NewLC( aObserver, aFileName ); + CleanupStack::Pop(self); + IRLOG_DEBUG( "CIRDataProvider::NewL(..., &aFileName) - Exiting." ); + return self; + } + +// --------------------------------------------------------------------------- +// CIRDataProvider::~CIRDataProvider() +// Destructs an instance of CIRDataProvider. +// --------------------------------------------------------------------------- +// +CIRDataProvider::~CIRDataProvider() // destruct - virtual, so no export + { + IRLOG_DEBUG( "CIRDataProvider::~CIRDataProvider() - Entering" ); + + if (iHttpDataProvider) + { + // Cancel any active transactions + iHttpDataProvider->CancelTransaction(); + // Destroy the data provider object + } + + delete iHttpDataProvider; + + if( iIRSettings ) + { + iIRSettings->Close(); + } + + if (iDataProviderTimer) + { + iDataProviderTimer->Cancel(); // Cancel the timer + } + + delete iDataProviderTimer; // Destroy the timer object + if( iResponseHeaders ) + { + delete iResponseHeaders; + } + iFile.Close(); + iFsSession.Close(); // Close the file server session + IRLOG_DEBUG( "CIRDataProvider::~CIRDataProvider() - Exiting" ); + } + +// General functions exported ( These are the API`s exposed )( HTTP ) + +// --------------------------------------------------------------------------- +// CIRDataProvider::IRHttpIssueRequest(TDesC8& aUri) +// Used to issue an Http request +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRDataProvider::IRHttpIssueRequestL( + CIRHttpRequestData &aRequestObject ) + { + IRHttpCancelRequest(); + IRLOG_DEBUG( "CIRDataProvider::IRHttpIssueRequestL - Entering" ); + IRRDEBUG2("CIRDATAPROVIDER::IRHTTPISSUEREQUESTL",KNullDesC); + CIRHttpResponseData* newResponseHeaders = new ( ELeave ) CIRHttpResponseData; + delete iResponseHeaders; + iResponseHeaders = newResponseHeaders; + + + // Create or replace the file used to store xml response from iSDS + User::LeaveIfError(iFile.Replace( iFsSession, iXmlFilePath, EFileWrite )); + iHttpDataProvider->CancelTransaction(); + + TInt err = iHttpDataProvider->IssueHttpRequestL( aRequestObject ); + // Cancel the timer if active + iDataProviderTimer->Cancel(); + // Start the timer for timeout + iDataProviderTimer->After( iTimeOut ); + if ( err == KErrCouldNotConnect ) + { + // If error in IssueHttpRequest then close the open file + iFile.Close(); + iDataProviderTimer->Cancel(); + iDataProviderObserver.IRHttpGeneralError( err ); + // Cancel any possibly pending transactions + iHttpDataProvider->CancelTransaction(); + } + + IRLOG_DEBUG( "CIRDataProvider::IRHttpIssueRequestL - Exiting." ); + } + + +// --------------------------------------------------------------------------- +// CIRDataProvider::IRHttpCancelRequest() +// Used to cancel a request +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRDataProvider::IRHttpCancelRequest() + { + IRLOG_DEBUG( "CIRDataProvider::IRHttpCancelRequest - Entering" ); + // Cancel the timer if active + iDataProviderTimer->Cancel(); + // Cancel any possibly pending transactions + iHttpDataProvider->CancelTransaction(); + // Close the file handle used to store the xml response + iFile.Close(); + IRLOG_DEBUG( "CIRDataProvider::IRHttpCancelRequest - Exiting." ); + } + + +// --------------------------------------------------------------------------- +// CIRDataProvider::ReleaseResources() +// Used to release the resources held by the IRHttpDataProvider +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRDataProvider::ReleaseResources() + { + IRLOG_DEBUG( "CIRDataProvider::ReleaseResources - Entering" ); + // Release the resources held by the IRHttpDataProvider + iHttpDataProvider->ReleaseResources(); + IRLOG_DEBUG( "CIRDataProvider::ReleaseResources - Exiting" ); + } + + +//These are the callback functions used by CIRHttpDataProvider to +//provide the CIRDataProvider with the data after processing the +//HTTP request. + +// --------------------------------------------------------------------------- +// CIRDataProvider::HttpEventComplete() +// Used to Indicate to the observer that the request event has completed +// --------------------------------------------------------------------------- +// +void CIRDataProvider::HttpEventComplete() + { + IRLOG_DEBUG( "CIRDataProvider::HttpEventComplete - Entering" ); + iFile.Close(); + iDataProviderTimer->Cancel(); + + // Need to take a member to a local variable, as the IRHttpDataReceived may initiate + // an IRHttpIssueRequestL() call, causing the headers to be replaced with empty ones, and + // causing crashes. + CIRHttpResponseData* currentHeaders = iResponseHeaders; + iResponseHeaders = NULL; // prevents the destructor to delete in case something streange happens. + iDataProviderObserver.IRHttpDataReceived( iXmlFilePath,*currentHeaders ); + + delete currentHeaders; + IRLOG_DEBUG( "CIRDataProvider::HttpEventComplete - Exiting." ); + } + + +void CIRDataProvider::ExtractHeaderValue(const TDesC8& aHeaderData,const + TDesC8& aHeaderName,const TDesC8& aDelimeter,TDes8& aHolder) const + { + IRLOG_DEBUG( "CIRDataProvider::ExtractHeaderValue - Entering" ); + TInt position = aHeaderData.Find(aHeaderName); + if( position >= 0) + { + TPtrC8 headerValue = aHeaderData.Mid(position); + TInt delimeterPosition = headerValue.Find(aDelimeter); + if( delimeterPosition != KErrNotFound ) + { + delimeterPosition++; + TPtrC8 value = headerValue.Mid(delimeterPosition); + aHolder.Copy(value); + aHolder.TrimAll(); + } + } + IRLOG_DEBUG( "CIRDataProvider::ExtractHeaderValue - Exiting." ); + } + + +// --------------------------------------------------------------------------- +// CIRDataProvider::HttpHeaderReceived( const TDesC8& aHeaderData ) +// Used by CIRHttpDataProvider to indicate that an HTTP header is received. +// --------------------------------------------------------------------------- +// +void CIRDataProvider::HttpHeaderReceived( const TDesC8& aHeaderData ) + { + IRLOG_DEBUG( "CIRDataProvider::HttpHeaderReceived - Entering." ); + _LIT8(KDelim,":"); + _LIT8(KContentType,"Content-Type"); + ExtractHeaderValue(aHeaderData,KContentType,KDelim,iResponseHeaders-> + iContentType); + _LIT8(KMaxAge,"max-age"); + _LIT8(KDelimEqual,"="); + ExtractHeaderValue(aHeaderData,KMaxAge,KDelimEqual,iResponseHeaders-> + iMaxAge); + _LIT8(KContentLength,"Content-Length"); + ExtractHeaderValue(aHeaderData,KContentLength,KDelim,iResponseHeaders-> + iContentLength); + _LIT8(KExpires,"Expires"); + ExtractHeaderValue(aHeaderData,KExpires,KDelim,iResponseHeaders->iExpires); + IRLOG_DEBUG( "CIRDataProvider::HttpHeaderReceived - Exiting." ); + } + + +void CIRDataProvider::HttpDateHeaderReceived(const TDesC8 &aHeader, + const TTime& aTime ) + { + IRLOG_DEBUG( "CIRDataProvider::HttpDateHeaderReceived - Entering." ); + _LIT8(KDate,"Date"); + _LIT8(KLastModified,"Last-Modified"); + TInt position = aHeader.Find(KDate); + if( position != KErrNotFound ) + { + iResponseHeaders->iDate = aTime; + //find the difference between device time and response time + //and storing the offset + SetOffsetSeconds( aTime ); + return ; + } + position = aHeader.Find(KLastModified); + if( position != KErrNotFound ) + { + iResponseHeaders->iLastModified = aTime; + } + IRLOG_DEBUG( "CIRDataProvider::HttpDateHeaderReceived - Exiting." ); + } + + + +// --------------------------------------------------------------------------- +// CIRDataProvider::HttpBodyReceived( const TDesC8& aBodyData ) +// Used by CIRHttpDataProvider to indicate that an HTTP response body +// is received. +// --------------------------------------------------------------------------- +// +void CIRDataProvider::HttpBodyReceived( const TDesC8 &aBodyData ) + { + IRLOG_DEBUG( "CIRDataProvider::HttpBodyReceived - Entering" ); + TInt FileWritePos = 0; + iFile.Seek( ESeekEnd, FileWritePos ); + iFile.Write( FileWritePos, aBodyData ); + IRLOG_DEBUG( "CIRDataProvider::HttpBodyReceived - Exiting." ); + } + +// --------------------------------------------------------------------------- +// CIRDataProvider::HttpTransactionError(TInt aErrCode) +// Used by CIRHttpDataProvider to indicate that a HTTP Transaction error +// has occured. +// --------------------------------------------------------------------------- +// +void CIRDataProvider::HttpTransactionError( TInt aErrCode ) + { + IRLOG_DEBUG( "CIRDataProvider::HttpTransactionError - Entering" ); + iFile.Close(); + iDataProviderTimer->Cancel(); + iDataProviderObserver.IRHttpGeneralError( aErrCode ); + // Cancel any possibly pending transactions + iHttpDataProvider->CancelTransaction(); + IRLOG_DEBUG( "CIRDataProvider::HttpTransactionError - Exiting." ); + } + +// --------------------------------------------------------------------------- +// CIRDataProvider::HttpResponseCodeRecieved(TInt aResponseCode) +// Used by CIRHttpDataProvider to indicate to the iSDS Client that a +// 304 Not Changed response received +// Note: Implemented in version 0.2 +// --------------------------------------------------------------------------- +// +void CIRDataProvider::HttpResponseCodeRecieved( TInt aResponseCode ) + { + IRLOG_DEBUG( "CIRDataProvider::HttpResponseCodeRecieved - Entering" ); + iDataProviderObserver.IRHttpResponseCodeReceived( aResponseCode, *iResponseHeaders ); + IRLOG_DEBUG( "CIRDataProvider::HttpResponseCodeRecieved- Exiting" ); + } + +// constructor support +// don't export these, because used only by functions in this DLL +// --------------------------------------------------------------------------- +// CIRDataProvider::CIRDataProvider(MIRDataProviderObserver& aObserver): +// iDataProviderObserver(aObserver) +// Default Constructor +// --------------------------------------------------------------------------- +// +void CIRDataProvider::TimerExpired() + { + IRLOG_INFO( "CIRDataProvider::TimerExpired - Entering" ); + IRHttpCancelRequest(); + HttpTransactionError( KDataProviderTimeout ); + IRLOG_INFO( "CIRDataProvider::TimerExpired - Exiting" ); + } + + + +CIRDataProvider::CIRDataProvider( MIRDataProviderObserver &aObserver ): + iDataProviderObserver( aObserver ) // first-phase C++ constructor + { + IRLOG_INFO( "CIRDataProvider::CIRDataProvider" ); + // Definition not required + } + +// --------------------------------------------------------------------------- +// void CIRDataProvider::ConstructL() +// 2nd Phase construction +// --------------------------------------------------------------------------- +// +void CIRDataProvider::ConstructL() // second-phase constructor + { + IRLOG_DEBUG( "CIRDataProvider::ConstructL - Entering" ); + _LIT( KXmlFile, "iSdsResponse.xml" ); + ConstructL(KXmlFile); + iHttpDataProvider->iSetNonUAProfUserAgent = EFalse; + IRLOG_DEBUG( "CIRDataProvider::ConstructL - Exiting" ); + } + +// --------------------------------------------------------------------------- +// void CIRDataProvider::ConstructL(TDesC& aFilePath) +// 2nd Phase construction +// --------------------------------------------------------------------------- +// +void CIRDataProvider::ConstructL( const TDesC &aFileName ) + { + IRLOG_DEBUG( "CIRDataProvider::ConstructL(const TDesC &aFileName) - Entering" ); + iHttpDataProvider = CIRHttpDataProvider::NewL( *this ); + iDataProviderTimer = CIRDataProviderTimer::NewL( EPriorityHigh, *this ); + User::LeaveIfError(iFsSession.Connect()); + iIRSettings = CIRSettings::OpenL(); + iXmlFilePath = iIRSettings->PrivatePath(); + iXmlFilePath.Append( aFileName ); + iTimeOut = iIRSettings->GetTimeOut(); + iHttpDataProvider->iSetNonUAProfUserAgent = ETrue; + IRLOG_DEBUG( "CIRDataProvider::ConstructL(const TDesC &aFileName) - Exiting." ); + } + + + +// --------------------------------------------------------------------------- +// CIRDataProvider::NewLC(MIRDataProviderObserver& aObserver) +// Creates instance of CIRDataProvider. +// --------------------------------------------------------------------------- +// +CIRDataProvider *CIRDataProvider::NewLC( MIRDataProviderObserver &aObserver ) + { + IRLOG_DEBUG( "CIRDataProvider::NewLC - Entering." ); + CIRDataProvider *self = new( ELeave )CIRDataProvider( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + IRLOG_DEBUG( "CIRDataProvider::NewLC - Exiting." ); + return self; + } + +// --------------------------------------------------------------------------- +// CIRDataProvider::NewLC(MIRDataProviderObserver& aObserver) +// Creates instance of CIRDataProvider. +// --------------------------------------------------------------------------- +// +CIRDataProvider *CIRDataProvider::NewLC( MIRDataProviderObserver &aObserver, + const TDesC &aFileName ) + { + IRLOG_DEBUG( "CIRDataProvider::NewLC - Entering." ); + CIRDataProvider *self = new( ELeave )CIRDataProvider( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL( aFileName ); + IRLOG_DEBUG( "CIRDataProvider::NewLC - Exiting." ); + return self; + } + +EXPORT_C CIRHttpDataProvider* CIRDataProvider::GetHttpDataProvider() +{ +IRLOG_DEBUG( "CIRDataProvider::GetHttpDataProvider" ); + return iHttpDataProvider; +} + +// --------------------------------------------------------------------------- +// CIRDataProvider::SetOffsetSeconds( const TTime& aTime ) +// Stores the offset between device time and response header in settings +// --------------------------------------------------------------------------- +// +void CIRDataProvider::SetOffsetSeconds( const TTime& aTime ) + { + IRLOG_DEBUG( "CIRDataProvider::SetOffsetSeconds - Entering" ); + TTime currenttime; + //calculates the current time + currenttime.UniversalTime(); + //finds offset from isds response + TTimeIntervalSeconds offsetseconds; + //Find offset from isds response + TInt err = currenttime.SecondsFrom(aTime,offsetseconds); + if( err ) + { + //if error offsetseconds is set to zero + offsetseconds = 0; + } + //storing the offset value in setting + TRAP_IGNORE( iIRSettings->SetTimeCorrectionL(offsetseconds.Int()) ) + IRLOG_DEBUG( "CIRDataProvider::SetOffsetSeconds - Exiting." ); + } + +