internetradio2.0/dataprovidersrc/irdataprovider.cpp
changeset 0 09774dfdd46b
child 12 608f67c22514
--- /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." );
+	}
+
+