genericpositioningplugins/locationsuplpsy/src/suplpsyrequestmanager.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 23 Jun 2010 18:40:52 +0300
changeset 32 b12ea03c50a3
parent 0 667063e416a2
permissions -rw-r--r--
Revision: 201023 Kit: 2010125

/*
* 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 <e32std.h>
#include <bacntf.h>
#include <lbs.h>      
#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