diff -r 63c982fb92f2 -r b73252188534 locationmanager/ReverseGeocode/src/clientengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locationmanager/ReverseGeocode/src/clientengine.cpp Thu Aug 19 10:20:41 2010 +0300 @@ -0,0 +1,673 @@ +/* +* Copyright (c) 2006-2009 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: Implementation of HTTP Client Engine. +*/ + +//Symbian headers +#include +#include +#include +#include +#include +#include // voice call notification +#include // kmmtsymodulename +#include "locationmanagerdebug.h" +#include "clientengine.h" + +// Used user agent for requests +_LIT8(KUserAgent, "SimpleClient 1.0"); + +// This client accepts all content types. +_LIT8(KAccept, "*/*"); + +// ---------------------------------------------------------------------------- +// CClientEngine::NewL() +// ---------------------------------------------------------------------------- +CClientEngine* CClientEngine::NewL( MClientObserver& aObserver) + { + LOG("CClientEngine::NewL ,begin"); + CClientEngine* self = CClientEngine::NewLC( aObserver); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------------------------- +// CClientEngine::NewLC() +// ---------------------------------------------------------------------------- +CClientEngine* CClientEngine::NewLC(MClientObserver& aObserver) + { + LOG("CClientEngine::NewLC ,begin"); + CClientEngine* self = new ( ELeave ) CClientEngine( aObserver); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// ---------------------------------------------------------------------------- +// CClientEngine::CClientEngine() +// ---------------------------------------------------------------------------- +CClientEngine::CClientEngine( MClientObserver& aObserver): + CActive( CActive::EPriorityStandard ), + iObserver( aObserver ), + iConnectionSetupDone( EFalse ), + iPrevProfileId( -1 ), + iMobility(NULL), + iTransactionOpen( EFalse ), + iUri(NULL) + { + } + +// ---------------------------------------------------------------------------- +// CClientEngine::~CClientEngine() +// ---------------------------------------------------------------------------- +CClientEngine::~CClientEngine() + { + LOG("CClientEngine::~CClientEngine ,begin"); + Cancel(); + + if ( iTransactionOpen ) + { + iTransaction.Close(); + iTransactionOpen = EFalse; + } + + if ( iMobility ) + { + iMobility->Cancel(); + } + delete iMobility; + iMobility = NULL; + + if(iConnectionSetupDone) + { + iSession.Close(); + iConnection.Close(); + iSocketServ.Close(); + } + delete iUri; + iUri = NULL; + + iCmManager.Close(); + + + // DON'T cose RMobilePhone object + + LOG("CClientEngine::~CClientEngine ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::ConstructL() +// ---------------------------------------------------------------------------- +void CClientEngine::ConstructL() + { + LOG("CClientEngine::ConstructL ,begin"); + CActiveScheduler::Add(this); + iCmManager.OpenL(); + LOG("CClientEngine::ConstructL ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::CloseConnection() +// ---------------------------------------------------------------------------- +void CClientEngine::CloseConnection() + { + LOG("CClientEngine::CloseConnection ,begin" ); + if ( iTransactionOpen ) + { + iTransaction.Close(); + iTransactionOpen = EFalse; + } + + if ( iMobility ) + { + iMobility->Cancel(); + delete iMobility; + iMobility = NULL; + } + + if(iConnectionSetupDone) + { + iSession.Close(); + iConnection.Close(); + iSocketServ.Close(); + + iConnectionSetupDone = EFalse; + } + LOG("CClientEngine::CloseConnection ,end"); + } + + +// ---------------------------------------------------------------------------- +// CClientEngine::IsVisitorNetwork() +// ---------------------------------------------------------------------------- +TBool CClientEngine::IsVisitorNetwork(const TMobileRoamingStatus& aRegNetworkStatus) const + { + LOG1("CClientEngine::IsVisitorNetwork. reg network status - %d", + (TInt) aRegNetworkStatus); + + return (aRegNetworkStatus == EMobileNationalRoaming || + aRegNetworkStatus== EMobileInternationalRoaming); + + } + +// ---------------------------------------------------------------------------- +// CClientEngine::IsWlanOnly() +// ---------------------------------------------------------------------------- +TBool CClientEngine::IsWlanOnly(const TMobileRoamingStatus& aRoamingStatus, + const TCmGenConnSettings& aGenConnSettings) const + { + LOG1("CClientEngine::IsVisitorNetwork. reg network status - %d",(TInt) aRoamingStatus); + TBool wlanOnlyFlag = EFalse; + switch(aRoamingStatus) + { + case EMobileRegHomeNetwork: + LOG("Home network"); + wlanOnlyFlag = (aGenConnSettings.iCellularDataUsageHome == ECmCellularDataUsageDisabled); + break; + case EMobileNationalRoaming: + case EMobileInternationalRoaming: + LOG("Visitor network"); + wlanOnlyFlag = (aGenConnSettings.iCellularDataUsageVisitor == ECmCellularDataUsageDisabled); + break; + default: + break; + } // end of switch + LOG1("Wlan only flag - %d", wlanOnlyFlag ? 1 : 0); + return wlanOnlyFlag; + } + + +// ---------------------------------------------------------------------------- +// CClientEngine::UeRegNetworkStatus() +// ---------------------------------------------------------------------------- +TMobileRoamingStatus CClientEngine::UeRegNetworkStatus() + { + LOG("CClientEngine::UeRegNetworkStatus() ,begin"); + TMobileRoamingStatus roamingStatus = EMobileNotRegistered; + if(iObserver.IsRegisteredAtHomeNetwork()) + { + // home network. + roamingStatus = EMobileRegHomeNetwork; + LOG("UE registered in home network"); + } + else + { + // roaming network + TBool homeNwInfoAvailableFlag = EFalse; + const RMobilePhone::TMobilePhoneNetworkInfoV1& homeNwInfo = + iObserver.GetHomeNetworkInfo(homeNwInfoAvailableFlag); + if(homeNwInfoAvailableFlag) + { + RMobilePhone::TMobilePhoneNetworkCountryCode countryCode = + iObserver.GetCurrentRegisterNw().iCountryCode; + if(countryCode.Compare(homeNwInfo.iCountryCode) == 0) + { + // national roaming.. + LOG("UE is in nation roaming"); + roamingStatus = EMobileNationalRoaming; + } + else + { + // international roaming. + LOG("UE is in international roaming"); + roamingStatus = EMobileInternationalRoaming; + } + } + } + if(roamingStatus == EMobileNotRegistered) + { + LOG("UE is not registered with the network. Offline mode."); + } + LOG("CClientEngine::UeRegNetworkStatus ,end"); + return roamingStatus; + } + +// ---------------------------------------------------------------------------- +// CClientEngine::IsDataConnectionAskAlwaysL() +// ---------------------------------------------------------------------------- +TBool CClientEngine::IsDataConnectionAskAlwaysL() + { + LOG("CClientEngine::IsDataConnectionAskAlwaysL ,begin"); + TMobileRoamingStatus roamingStatus = UeRegNetworkStatus(); + + TCmGenConnSettings genConnSettings; + TBool retVal = EFalse; + iCmManager.ReadGenConnSettingsL(genConnSettings); + + LOG1("wlan usage - %d", genConnSettings.iUsageOfWlan); + LOG1("Home usage - %d", genConnSettings.iCellularDataUsageHome); + LOG1("Visitor usage - %d", genConnSettings.iCellularDataUsageVisitor); + + if((IsWlanOnly(roamingStatus, genConnSettings) && genConnSettings.iUsageOfWlan == ECmUsageOfWlanManual) // wlan + || (roamingStatus == EMobileRegHomeNetwork && // home + genConnSettings.iCellularDataUsageHome == ECmCellularDataUsageConfirm) + || (IsVisitorNetwork(roamingStatus) && // roaming + genConnSettings.iCellularDataUsageVisitor == ECmCellularDataUsageConfirm) + ) + { + retVal = ETrue; + } + LOG("CClientEngine::IsDataConnectionAskAlwaysL ,end"); + return retVal; + } + +// ---------------------------------------------------------------------------- +// CClientEngine::SetupConnectionL() +// ---------------------------------------------------------------------------- +void CClientEngine::SetupConnectionL( const TConnectionOption aOption ) + { + LOG("CClientEngine::SetupConnectionL ,begin"); + if ( aOption == ESilent && IsDataConnectionAskAlwaysL()) + { + LOG("Silent mode. connection setup is asked always."); + if ( iConnectionSetupDone ) + { + LOG("Already connected. Close the connection\n"); + CloseConnection(); + } + User::Leave(KErrNotSupported); + } + if ( iConnectionSetupDone ) + { + // Connection setup is done + LOG("Already connected.\n"); + User::Leave(KErrAlreadyExists); + } + + + LOG1("SetupConnectionL: connection option: %d\n", aOption ); + + // Open HTTP Session + iSession.OpenL(); + User::LeaveIfError(iSocketServ.Connect()); + User::LeaveIfError(iConnection.Open(iSocketServ)); + + if ( aOption == ESilent ) + { + // Create overrides + TConnPrefList prefList; + TExtendedConnPref prefs; + prefs.SetSnapPurpose( CMManager::ESnapPurposeInternet ); + prefs.SetNoteBehaviour( TExtendedConnPref::ENoteBehaviourConnSilent ); + prefList.AppendL( &prefs ); + + iConnection.Start(prefList, iStatus); + } + else + { + iConnection.Start( iStatus ); + } + + + SetActive(); + LOG("CClientEngine::SetupConnectionL ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::SetHeaderL() +// ---------------------------------------------------------------------------- +void CClientEngine::SetHeaderL( RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue ) + { + LOG("CClientEngine::SetHeaderL ,begin"); + RStringF valStr = iSession.StringPool().OpenFStringL( aHdrValue ); + CleanupClosePushL( valStr ); + THTTPHdrVal val(valStr); + aHeaders.SetFieldL( iSession.StringPool().StringF( aHdrField, RHTTPSession::GetTable()), val); + CleanupStack::PopAndDestroy(); // valStr + LOG("CClientEngine::SetHeaderL ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::IssueHTTPGetL() +// ---------------------------------------------------------------------------- +void CClientEngine::IssueHTTPGetL( const TDesC8& aUri, const TConnectionOption aOption ) + { + LOG("CClientEngine::IssueHTTPGetL ,begin"); + if ( IsActive() ) + { + // If there is some request in pending state + // return with out further processing + // Should we leave here !? + LOG("Client engine is already active"); + return; + } + + delete iUri; + iUri = NULL; + + iUri = aUri.AllocL(); + + // Create HTTP connection + TRAPD( err, SetupConnectionL( aOption ) ); + //If the Err is KErrNone, It will lead to RunL and + //hence jump to the DoHTTPGetL() from there. + + if( err == KErrAlreadyExists ) + { + DoHTTPGetL(); + } + else if( err != KErrNone ) + { + LOG("Connection failure. Leaving."); + iObserver.ClientEvent( EHttpConnectionFailure ); + User::Leave(err); + } + iEngineState = EGet; + LOG("CClientEngine::IssueHTTPGetL ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::DoHTTPGetL() +// ---------------------------------------------------------------------------- +void CClientEngine::DoHTTPGetL() + { + LOG("CClientEngine::DoHTTPGetL ,begin"); + // Parse string to URI (as defined in RFC2396) + TUriParser8 uri; + uri.Parse( *iUri ); + + // Get request method string for HTTP GET + RStringF method = iSession.StringPool().StringF( HTTP::EGET,RHTTPSession::GetTable() ); + + // Open transaction with previous method and parsed uri. This class will + // receive transaction events in MHFRunL and MHFRunError. + iTransaction = iSession.OpenTransactionL( uri, *this, method ); + iTransactionOpen = ETrue; + + // Set headers for request; user agent and accepted content type + RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection(); + SetHeaderL( hdr, HTTP::EUserAgent, KUserAgent ); + SetHeaderL( hdr, HTTP::EAccept, KAccept ); + + // Submit the transaction. After this the framework will give transaction + // events via MHFRunL and MHFRunError. + iTransaction.SubmitL(); + + iObserver.ClientEvent( EHttpConnecting ); + LOG("CClientEngine::DoHTTPGetL ,end"); +} + +// ---------------------------------------------------------------------------- +// CClientEngine::CancelTransaction() +// ---------------------------------------------------------------------------- +void CClientEngine::CancelTransaction() + { + LOG("CClientEngine::CancelTransaction ,begin"); + iEngineState = EIdle; + delete iUri; + iUri = NULL; + + // Close() also cancels transaction (Cancel() can also be used but + // resources allocated by transaction must be still freed with Close()) + if( iTransactionOpen ) + { + iTransaction.Close(); + iTransactionOpen = EFalse; + + iObserver.ClientEvent( EHttpTxCancelled ); + } + LOG("CClientEngine::CancelTransaction ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::MHFRunL() +// ---------------------------------------------------------------------------- +void CClientEngine::MHFRunL( RHTTPTransaction aTransaction, const THTTPEvent& aEvent ) + { + LOG("CClientEngine::MHFRunL ,begin"); + switch ( aEvent.iStatus ) + { + case THTTPEvent::EGotResponseHeaders: + { + // HTTP response headers have been received. Use + // aTransaction.Response() to get the response. However, it's not + // necessary to do anything with the response when this event occurs. + iObserver.ClientEvent( EHttpHdrReceived ); + break; + } + case THTTPEvent::EGotResponseBodyData: + { + // Part (or all) of response's body data received. Use + // aTransaction.Response().Body()->GetNextDataPart() to get the actual + // body data. + + // Get the body data supplier + MHTTPDataSupplier* body = aTransaction.Response().Body(); + TPtrC8 dataChunk; + + // GetNextDataPart() returns ETrue, if the received part is the last + // one. + TBool isLast = body->GetNextDataPart(dataChunk); + iObserver.ClientBodyReceived(dataChunk); + + iObserver.ClientEvent( EHttpBytesReceieved ); + + // NOTE: isLast may not be ETrue even if last data part received. + // (e.g. multipart response without content length field) + // Use EResponseComplete to reliably determine when body is completely + // received. + if( isLast ) + { + iObserver.ClientEvent( EHttpBodyReceieved ); + } + // Always remember to release the body data. + body->ReleaseData(); + break; + } + case THTTPEvent::EResponseComplete: + { + // Indicates that header & body of response is completely received. + // No further action here needed. + + iObserver.ClientEvent( EHttpTxCompleted ); + break; + } + case THTTPEvent::ESucceeded: + { + // Indicates that transaction succeeded. + iObserver.ClientEvent( EHttpTxSuccess ); + // Transaction can be closed now. It's not needed anymore. + aTransaction.Close(); + iTransactionOpen = EFalse; + break; + } + case THTTPEvent::EFailed: + { + // Transaction completed with failure. + iObserver.ClientEvent( EHttpTxFailed ); + aTransaction.Close(); + iTransactionOpen = EFalse; + break; + } + default: + // There are more events in THTTPEvent, but they are not usually + // needed. However, event status smaller than zero should be handled + // correctly since it's error. + { + if ( aEvent.iStatus < 0 ) + { + iObserver.ClientEvent( EHttpConnectionFailure ); + // Close the transaction on errors + aTransaction.Close(); + iTransactionOpen = EFalse; + } + break; + } + } + LOG("CClientEngine::MHFRunL ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::MHFRunError() +// ---------------------------------------------------------------------------- +TInt CClientEngine::MHFRunError( TInt /*aError*/, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/ ) + { + LOG("CClientEngine::MHFRunError ,begin"); + // Just notify about the error and return KErrNone. + CloseConnection(); + iObserver.ClientEvent(EHttpMhfRunError); + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CClientEngine::PreferredCarrierAvailable() +// ---------------------------------------------------------------------------- +void CClientEngine::PreferredCarrierAvailable( TAccessPointInfo /*aOldAPInfo*/, + TAccessPointInfo /*aNewAPInfo*/, + TBool /*aIsUpgrade*/, + TBool aIsSeamless ) + { + LOG("CClientEngine::PreferredCarrierAvailable ,begin"); + if( !aIsSeamless && iMobility) + { + iMobility->MigrateToPreferredCarrier(); + } + LOG("CClientEngine::PreferredCarrierAvailable ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::NewCarrierActive() +// ---------------------------------------------------------------------------- +void CClientEngine::NewCarrierActive( TAccessPointInfo /*aNewAPInfo*/, + TBool aIsSeamless ) + { + LOG("CClientEngine::NewCarrierActive ,begin"); + if( !aIsSeamless && iMobility) + { + iMobility->NewCarrierAccepted(); + } + LOG("CClientEngine::NewCarrierActive ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::Error() +// ---------------------------------------------------------------------------- +void CClientEngine::Error(TInt /*aError*/) + { + LOG("CClientEngine::Error"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::DoCancel() +// ---------------------------------------------------------------------------- +void CClientEngine::DoCancel() + { + LOG("CClientEngine::DoCancel"); + iConnection.Stop(); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::DoCancel() +// ---------------------------------------------------------------------------- +TInt CClientEngine::RunError(TInt /*aError*/) + { + LOG("CClientEngine::RunError"); + // Just notify about the error and return KErrNone. + CloseConnection(); + iObserver.ClientEvent( EHttpTxFailed ); + return KErrNone; + } +// ---------------------------------------------------------------------------- +// CClientEngine::RunL() +// ---------------------------------------------------------------------------- +void CClientEngine::RunL() + { + LOG1("CClientEngine::RunL: error is: %d\n", iStatus.Int() ); + TInt statusCode = iStatus.Int(); + if ( statusCode == KErrNone ) + { + // Connection done ok + iConnectionSetupDone = ETrue; + + RStringPool strPool = iSession.StringPool(); + + // Remove first session properties just in case. + RHTTPConnectionInfo connInfo = iSession.ConnectionInfo(); + + // Clear RConnection and Socket Server instances + connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketServ,RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketConnection,RHTTPSession::GetTable())); + + // Clear the proxy settings + connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyUsage,RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyAddress,RHTTPSession::GetTable())); + + // RConnection and Socket Server + connInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketServ, + RHTTPSession::GetTable()), + THTTPHdrVal (iSocketServ.Handle()) ); + + TInt connPtr1 = REINTERPRET_CAST(TInt, &iConnection); + connInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable() ), THTTPHdrVal (connPtr1) ); + + // Register for mobility API + if(iMobility) + { + delete iMobility; + iMobility = NULL ; + } + iMobility = CActiveCommsMobilityApiExt::NewL( iConnection, *this ); + // Start selected HTTP action + switch( iEngineState ) + { + case EIdle: + { + // + CancelTransaction(); + break; + } + case EGet: + { + DoHTTPGetL(); + break; + } + }; + } + else + { + //handle error + if ( statusCode == KErrPermissionDenied ) + { + iObserver.ClientEvent( EHttpAuthFailed ); + } + else + { + //Throw some general Transaction falure error! + iObserver.ClientEvent( EHttpTxFailed ); + } + CloseConnection(); + } + LOG("CClientEngine::RunL ,end"); + } + +// ---------------------------------------------------------------------------- +// CClientEngine::SilentConnectionAllowed() +// ---------------------------------------------------------------------------- +TBool CClientEngine::SilentConnectionAllowed() + { + LOG("CClientEngine::SilentConnectionAllowed ,begin"); + TBool retVal = EFalse; + TRAPD(err, retVal = IsDataConnectionAskAlwaysL()); + if(err == KErrNone) + { + // data connection is always ask... Silent connection is not allowed + retVal = !retVal; + } + LOG1("CClientEngine::SilentConnectionAllowed ,end. Ret - %d", retVal); + return retVal; + } + +// End of file +