diff -r 000000000000 -r 667063e416a2 genericpositioningplugins/locationsuplpsy/src/suplpsyrequestmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericpositioningplugins/locationsuplpsy/src/suplpsyrequestmanager.cpp Tue Feb 02 01:06:48 2010 +0200 @@ -0,0 +1,472 @@ +/* +* Copyright (c) 2005 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: This is SUPL PSY location request manager +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include "suplpsyrequestmanager.h" +#include "suplpsyrequestor.h" +#include "suplpsyrequestcompletelistener.h" +#include "suplpsylogging.h" +#include "suplpsypanic.h" +#include "suplpsyinfostoremanager.h" + + +// LOCAL CONSTANTS AND MACROS + +// =========================== == LOCAL FUNCTIONS =============================== + +// ========================== == MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::CSuplPsyRequestManager +// C++default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CSuplPsyRequestManager::CSuplPsyRequestManager(): iSuplPsyCellIdHandler( NULL ), + iSuplPsyInfoStoreManager( NULL ), + iMaxAge( 0 ) + { + // Nothing to do here + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::ConstructL() + { + TRACESTRING( "CSuplPsyRequestManager::ConstructL start" ) + + //Construct requestor + iRequestor = CSuplPsyRequestor::NewL( + TCallBack( LocationRequestCompleteStatic, this ) ); + + //Construct environment change notifier + iEnvChangeNotifier = + CEnvironmentChangeNotifier::NewL( + CActive::EPriorityStandard, + TCallBack( NotifierCallBack, this ) ); + iSuplPsyCellIdHandler = CSuplPsyCellIdHandler::NewL( *this ); + + iSuplPsyInfoStoreManager = CSuplPsyInfoStoreManager::NewL(); + + iEnvChangeNotifier->Start(); + TRACESTRING( "CSuplPsyRequestManager::ConstructL end" ) + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::RegisterL +// ----------------------------------------------------------------------------- +// +CSuplPsyRequestManager* CSuplPsyRequestManager::RegisterL( + MSuplPsyRequestCompleteListener& aPositioner ) + { + CSuplPsyRequestManager* self = reinterpret_cast < CSuplPsyRequestManager* > + ( Dll::Tls() ); + + if ( self == NULL ) + { + self = new( ELeave ) CSuplPsyRequestManager; + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + Dll::SetTls( self ); + } + + self->RegisterPositionerL( aPositioner ); + return self; + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::~CSuplPsyRequestManager +// Destructor +// ----------------------------------------------------------------------------- +// +CSuplPsyRequestManager::~CSuplPsyRequestManager() + { + delete iRequestor; + + iPositionerArray.Reset(); + iPositionerArray.Close(); + + // Delete environment change notifier + if ( iEnvChangeNotifier != NULL ) + { + iEnvChangeNotifier->Cancel(); + delete iEnvChangeNotifier; + } + + delete iSuplPsyCellIdHandler; + iSuplPsyCellIdHandler = NULL; + + delete iSuplPsyInfoStoreManager; + iSuplPsyInfoStoreManager = NULL; + TRACESTRING( "CSuplPsyRequestManager:: destructed" ) + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::NotifyPositionUpdate +// +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::NotifyPositionUpdate ( + MSuplPsyRequestCompleteListener& aPositioner ) + { + TInt index = FindPositioner( aPositioner ); + if ( index != KErrNotFound ) + { + iPositionerArray[index].iRequested = ETrue; + // Issue request to get current cell id info + iSuplPsyCellIdHandler->GetCellID( iCellIdInfo ); + } + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::CancelNotifyPositionUpdate +// +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::CancelNotifyPositionUpdate ( + MSuplPsyRequestCompleteListener& aPositioner ) + { + TInt index = FindPositioner( aPositioner ); + if ( index != KErrNotFound ) + { + iPositionerArray[index].iRequested = EFalse; + + if ( !IsActiveLocationRequest() ) + { + iRequestor->Cancel(); + } + } + } + + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::RegisterPositionerL +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::RegisterPositionerL( + MSuplPsyRequestCompleteListener& aPositioner ) + { + //Panic if the positiner has already registered + if ( FindPositioner( aPositioner ) != KErrNotFound ) + { + Panic( EPanicPositionerAlreadyRegistered ); + } + + TPositionerStatus status; + status.iPositioner = &aPositioner; + status.iRequested = EFalse; + User::LeaveIfError( iPositionerArray.Append( status ) ); + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::FindPositioner +// ----------------------------------------------------------------------------- +// +TInt CSuplPsyRequestManager::FindPositioner( + MSuplPsyRequestCompleteListener& aPositioner ) const + { + TInt count = iPositionerArray.Count(); + for ( TInt i = 0; i < count; i++ ) + { + if ( iPositionerArray[i].iPositioner == &aPositioner ) + { + return i; + } + } + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::Unregister +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::Unregister( + MSuplPsyRequestCompleteListener& aPositioner ) + { + TInt index = FindPositioner( aPositioner ); + if ( index != KErrNotFound ) + { + iPositionerArray.Remove( index ); + } + + //Delete this instance if no positioner is registered + if ( iPositionerArray.Count() == 0 ) + { + delete this; + Dll::SetTls( NULL ); + } + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::IsActiveLocationRequest +// ----------------------------------------------------------------------------- +// +TBool CSuplPsyRequestManager::IsActiveLocationRequest() const + { + TInt count = iPositionerArray.Count(); + for ( TInt i = 0; i < count; i++ ) + { + if ( iPositionerArray[i].iRequested ) + { + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::LocationRequestComplete +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::LocationRequestComplete() + { + // Update the Cell id information from SUPL FW + TCellIdInfo cellinfofw; + + TInt errCIdfw = iSuplPsyInfoStoreManager->ReadSuplFwCellIdInfo( cellinfofw ); + + if( KErrNone == errCIdfw ) + { + // Log supl fw cid info + TRACESTRING2("supl fw Cid=%d",cellinfofw.iCid ) + TRACESTRING2("supl fw Lac=%d",cellinfofw.iLac ) + TRACESTRING2("supl fw MCC=%d",cellinfofw.iMCC ) + TRACESTRING2("supl fw MNC=%d",cellinfofw.iMNC ) + TInt er = iSuplPsyInfoStoreManager->WriteSuplPsyCellIdInfo( cellinfofw );//Ignore the error + TRACESTRING2("cenrep write error=%d",er ) + } + + + // Update the location information + iSuplPsyInfoStoreManager->WriteSuplPsyLocationInfo( GetPosition() );//Ignore the error + TInt err = iRequestor->GetRequestResult(); + + //Complete all requests + TInt count = iPositionerArray.Count(); + for ( TInt i = 0; i < count; i++ ) + { + TPositionerStatus& positionerStatus = iPositionerArray[i]; + if ( positionerStatus.iRequested ) + { + TBool completed = positionerStatus.iPositioner->RequestComplete( + err, + iRequestor->GetLocation() ); + + if ( completed ) + { + positionerStatus.iRequested = EFalse; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::LocationRequestCompleteStatic +// ----------------------------------------------------------------------------- +// +TInt CSuplPsyRequestManager::LocationRequestCompleteStatic( TAny* aAny ) + { + reinterpret_cast < CSuplPsyRequestManager* >( aAny )->LocationRequestComplete(); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::IsLastPostionValid +// ----------------------------------------------------------------------------- +// +TBool CSuplPsyRequestManager::IsLastPostionValid( TTime aMaxAge ) const + { + TRACESTRING( "CSuplPsyRequestManager:: IsLastPostionValid" ) + TPosition position; + iRequestor->GetLocation().GetPosition( position ); + + return ( aMaxAge > 0 && position.Time() >= aMaxAge ); + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::GetPosition +// ----------------------------------------------------------------------------- +const HPositionGenericInfo& CSuplPsyRequestManager::GetPosition() + { + return iRequestor->GetLocation(); + } + + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::NotifierCallBack +// ----------------------------------------------------------------------------- +TInt CSuplPsyRequestManager::NotifierCallBack( TAny* aPtr ) + { + reinterpret_cast < CSuplPsyRequestManager* >( aPtr )->HandleEnvironmentChange(); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager:HandleEnvironmentChange +// +// Currently we are only interested of system time change. This function is also +// called once immediately after enviroment change notifier object is +// constructed. +// +// NOTE: This function can be used to detect changes in phone power supply +// in case this information is needed to change the functionality depending of +// whether external power supply is connected or not. +// +// ( other items were commented in a header ). +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::HandleEnvironmentChange() + { + // Get reason why this function was called + TInt envChange = iEnvChangeNotifier->Change(); + + // If reason was cancel, or system time change flag is not on, then we + // can return. + if ( envChange == KErrCancel || !( envChange & EChangesSystemTime ) ) + { + return; + } + + // If system time really changed, then we set last fix time as 0 + iRequestor->ResetLastPosition(); + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::BasicCellIDRequestCompletedL +// +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::BasicCellIDRequestCompletedL( TInt aErrorCode ) + { + TRACESTRING( "CSuplPsyRequestManager::BasicCellIDRequestCompletedL start" ) + + TRACESTRING2("Request Completed with Error Code: %d",aErrorCode ) + + TBool requestSuplFw = ETrue; + + if( KErrNone == aErrorCode ) + { + // Log current cell id info + TRACESTRING2("Current Cid=%d",iCellIdInfo.iCid ) + TRACESTRING2("Current Lac=%d",iCellIdInfo.iLac ) + TRACESTRING2("Current MCC=%d",iCellIdInfo.iMCC ) + TRACESTRING2("Current MNC=%d",iCellIdInfo.iMNC ) + + // Get stored cell id from cenrep + + CSuplPsyCellIdHandler::TNetworkTypeInfo type = iSuplPsyCellIdHandler->NetworkType(); + TCellIdInfo cellinfo; + TInt errCId = iSuplPsyInfoStoreManager->ReadSuplPsyCellIdInfo( cellinfo ); + + + HPositionGenericInfo* posinfo = HPositionGenericInfo::NewLC(); + TInt errPosInfo = iSuplPsyInfoStoreManager->ReadSuplPsyLocationInfo( *posinfo ); + + // Validity of cell id info + TRACESTRING2("Validity of cell id info=%d",errCId ) + + // Presence of saved location info + TRACESTRING2("Saved Location info is present=%d",errPosInfo ) + + if( KErrNone == errCId && KErrNone == errPosInfo) + { + TRACESTRING( "Valid Cell Id & Location stored info exists" ) + + // Log saved cell id info + TRACESTRING2("Saved Cid=%d",cellinfo.iCid ) + TRACESTRING2("Saved Lac=%d",cellinfo.iLac ) + TRACESTRING2("Saved MCC=%d",cellinfo.iMCC ) + TRACESTRING2("Saved MNC=%d",cellinfo.iMNC ) + + TPosition pos; + posinfo->GetPosition( pos ); + + TRACESTRING2( "Max Age=%d",iMaxAge.Int64() ) + TRACESTRING2( "Fix Time=%d",pos.Time().Int64() ) + + // Check if max age expires + if( iMaxAge > 0 && pos.Time() >= iMaxAge ) + { + TRACESTRING( "Max age not expired" ) + // Check if current cell id is same as stored one. + if( iCellIdInfo.iCid == cellinfo.iCid && + ( iCellIdInfo.iLac == cellinfo.iLac || + CSuplPsyCellIdHandler:: EWCDMA == iSuplPsyCellIdHandler->NetworkType() ) && + iCellIdInfo.iMCC == cellinfo.iMCC && + iCellIdInfo.iMNC == cellinfo.iMNC ) + { + TRACESTRING( "Current CID info is same as stored one" ) + // completes client's request with stored position info + TInt count = iPositionerArray.Count(); + for ( TInt i = 0; i < count; i++ ) + { + TPositionerStatus& positionerStatus = iPositionerArray[i]; + if ( positionerStatus.iRequested ) + { + TBool completed = positionerStatus.iPositioner->RequestComplete( + aErrorCode,*posinfo ); + if ( completed ) + { + positionerStatus.iRequested = EFalse; + } + } + } + TRACESTRING( "Clients request completed with stored location info" ) + requestSuplFw = EFalse; + } + } + } + CleanupStack::PopAndDestroy( posinfo ); + } + + if( requestSuplFw ) + { + TRACESTRING( "Issuing Location Request..." ) + //Issue location request to SUPL FW + iRequestor->RequestLocation(); + } + TRACESTRING( "CSuplPsyRequestManager::BasicCellIDRequestCompletedL end" ) + } + +// ----------------------------------------------------------------------------- +// CSuplPsyRequestManager::RecieveMaxAge +// +// ----------------------------------------------------------------------------- +// +void CSuplPsyRequestManager::RecieveMaxAge( TTime aMaxAge ) + { + iMaxAge = aMaxAge; + } +// End of File