locationrequestmgmt/locationserver/src/EPos_CPosSubSession.cpp
changeset 0 9cfd9a3ee49c
child 48 81c9bee26a45
child 52 29dbbeac905d
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <e32base.h>
       
    20 #include <s32mem.h>
       
    21 #ifdef SYMBIAN_FEATURE_MANAGER
       
    22 	#include <featdiscovery.h>
       
    23 	#include <featureuids.h>
       
    24 #endif
       
    25 #include <lbs.h>
       
    26 #include <lbs/lbsadmin.h>
       
    27 #include "lbslocservermessageenums.h"
       
    28 #include <lbs/epos_cposmodules.h>
       
    29 #include <lbs/epos_mposmodulesobserver.h>
       
    30 #include "epos_proxypositionerconstructparams.h"
       
    31 #include "lbsdevloggermacros.h"
       
    32 
       
    33 #include "epos_cposmodulessettings.h"
       
    34 #include "EPos_Global.h"
       
    35 #include "EPos_ServerPanic.h"
       
    36 #include "EPos_CPositionRequest.h"
       
    37 #include "EPos_CPosSubSession.h"
       
    38 
       
    39 
       
    40 #include "EPos_CPosLocMonitorReqHandlerHub.h"
       
    41 
       
    42 // CONSTANTS
       
    43 #ifdef _DEBUG
       
    44 _LIT(KTraceFileName, "EPos_CPosSubSession.cpp");
       
    45 #endif
       
    46 
       
    47 const TInt KParamRequestorType = 0;
       
    48 const TInt KParamRequestorFormat = 1;
       
    49 const TInt KParamRequestorData = 2;
       
    50 const TInt KParamRequestorStack = 0;
       
    51 const TInt KParamUpdateOptions = 0;
       
    52 
       
    53 
       
    54 // ==================== LOCAL FUNCTIONS ====================
       
    55 
       
    56 // ---------------------------------------------------------
       
    57 // ResetAndDestroy Used for cleanup.
       
    58 // This function is passed to a TCleanupItem
       
    59 // ---------------------------------------------------------
       
    60 //
       
    61 void ResetAndDestroyRRequestorStack(TAny* aPtr)
       
    62     {
       
    63     (reinterpret_cast<RRequestorStack*> (aPtr))->ResetAndDestroy();
       
    64     }
       
    65 
       
    66 // ================= MEMBER FUNCTIONS =======================
       
    67 
       
    68 /**
       
    69  *  C++ default constructor
       
    70  */
       
    71 CPosSubSession::CPosSubSession() : iRequestors()
       
    72     {
       
    73     
       
    74     }
       
    75 
       
    76 /**
       
    77  *  Symbian default constructor
       
    78  */
       
    79 void CPosSubSession::ConstructL(
       
    80         CPosModuleSettings& aModuleSettings,
       
    81         CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub,
       
    82         TPositionModuleId aImplementationUid,
       
    83         MPosStatusObserver* aStatusObserver,
       
    84         MPosModuleStatusManager* aModuleStatusManager,
       
    85         TBool aIsProxy)
       
    86     {
       
    87     TProxyPositionerConstructParams positionerParams;
       
    88     positionerParams.iImplementationUid = aImplementationUid;
       
    89     positionerParams.iStatusObserver = aStatusObserver;
       
    90     positionerParams.iParamObserver = this;
       
    91     positionerParams.iModuleSettingsManager = &aModuleSettings;
       
    92     positionerParams.iModuleStatusManager = aModuleStatusManager; 
       
    93 
       
    94 	iPositionRequest = CPositionRequest::NewL(
       
    95         aModuleSettings,
       
    96         aLocMonitorReqHandlerHub,
       
    97         positionerParams, 
       
    98         aIsProxy);
       
    99 	
       
   100 
       
   101 
       
   102 
       
   103 	//Need to call it to propogate iPsyDefaultUpdateTimeOut in case  
       
   104 	//SetPsyDefaultUpdateTimeOut was called in the CPositionRequest::NewL
       
   105 	//See SetPsyDefaultUpdateTimeOut implementation
       
   106 	SetPsyDefaultUpdateTimeOut(iPsyDefaultUpdateTimeOut);
       
   107 
       
   108 	iLocMonitorReqHandlerHub = &aLocMonitorReqHandlerHub;
       
   109     
       
   110 #ifdef SYMBIAN_FEATURE_MANAGER
       
   111 	iLocationManagementSupported = CFeatureDiscovery::IsFeatureSupportedL(NFeature::KLocationManagement);
       
   112 #else
       
   113 	__ASSERT_ALWAYS(EFalse, User::Invariant());	// Would happen on older versions of symbian OS if this code ever backported
       
   114 #endif    
       
   115 	
       
   116 	if(iLocationManagementSupported)
       
   117 		{
       
   118 		iAdmin = CLbsAdmin::NewL();
       
   119 		// connect to network registration status interface
       
   120 		iNetRegStatus.OpenL();
       
   121 		}
       
   122     }
       
   123 
       
   124 /**
       
   125  * Two-phased constructor.
       
   126  *
       
   127  * @param aLastPositionHandler Last position handler.
       
   128  * @param aModulesDb the position log database.
       
   129  * @param aImplementationUid the positioner implementation uid.
       
   130  * @param aIsProxy ETrue if aImplementationUid represents a proxy PSY,
       
   131  *                 EFalse otherwise.
       
   132  * @param aStatusObserver status observer to be used by positioner.
       
   133  * @param aLocMonSession Location Monitor session handle shared by all subsessions
       
   134  */
       
   135 CPosSubSession* CPosSubSession::NewLC(
       
   136     CPosModuleSettings& aModuleSettings,
       
   137     CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub,
       
   138     TUid aImplementationUid,
       
   139     TBool aIsProxy,
       
   140     MPosStatusObserver* aStatusObserver,
       
   141     MPosModuleStatusManager* aModuleStatusManager)
       
   142 
       
   143     {
       
   144     CPosSubSession* self = new (ELeave) CPosSubSession();
       
   145     CleanupClosePushL(*self);
       
   146     
       
   147     self->ConstructL(
       
   148         aModuleSettings, 
       
   149         aLocMonitorReqHandlerHub, 
       
   150         aImplementationUid, 
       
   151         aStatusObserver, 
       
   152         aModuleStatusManager,
       
   153         aIsProxy);
       
   154         
       
   155     return self;
       
   156     }
       
   157 
       
   158 /**
       
   159  * Destructor.
       
   160  */
       
   161 CPosSubSession::~CPosSubSession()
       
   162     {
       
   163     if(iLocationManagementSupported)
       
   164     	{
       
   165     	delete iAdmin;
       
   166     	iNetRegStatus.Close();
       
   167     	}
       
   168     iRequestors.ResetAndDestroy();    
       
   169     delete iPositionRequest;
       
   170 
       
   171     }
       
   172 
       
   173 
       
   174 /**
       
   175  * This function is responsible for handling the
       
   176  * servicing of client requests to the server.
       
   177  * It uses the message passed as an argument to
       
   178  * obtain the request opcode and to access client
       
   179  * addresses for reading and writing.
       
   180  *
       
   181  * @param aMessage The current message
       
   182  */
       
   183 void CPosSubSession::ServiceL(const RMessage2& aMessage)
       
   184     {
       
   185     switch (aMessage.Function())
       
   186         {
       
   187 	    case ELbsSetSingleRequestor:
       
   188 		    HandleSetRequestorL(aMessage);
       
   189 		    break;
       
   190 	    case ELbsSetMultipleRequestors:
       
   191 		    HandleSetRequestorStackL(aMessage);
       
   192 		    break;
       
   193 	    case ELbsSetUpdateOptions:
       
   194 		    HandleSetUpdateOptionsL(aMessage);
       
   195 		    break;
       
   196 	    case ELbsGetUpdateOptions:
       
   197 		    HandleGetUpdateOptionsL(aMessage);
       
   198 		    break;
       
   199 	    case ELbsGetLastKnownPosition:
       
   200 			LBS_RDEBUG("Client", "LBS", "GetLastKnownPosition");
       
   201 		    HandleGetLastKnownPositionL(aMessage);
       
   202 		    break;
       
   203 	    case ELbsGetLastKnownPositionArea:
       
   204 	    	HandleGetLastKnownPositionAreaL(aMessage); 
       
   205 	    	break;
       
   206 	    case ELbsPosNotifyPositionUpdate:
       
   207 			LBS_RDEBUG("Client", "LBS", "NotifyPositionUpdate");
       
   208 		    HandleNotifyPositionUpdateL(aMessage);
       
   209 		    break;
       
   210 	    case ELbsPositionerCancelAsyncRequest:
       
   211 			LBS_RDEBUG("Client", "LBS", "CancelAsyncRequest");
       
   212             HandleCancelAsyncRequestL(aMessage);
       
   213             break;
       
   214         default:
       
   215         	DEBUG_TRACE("default switch case subsession ", __LINE__)
       
   216             User::Leave(KErrNotSupported);
       
   217 		    break;
       
   218         }
       
   219     }
       
   220 
       
   221 /**
       
   222  * From MPosParameterObserver.
       
   223  *
       
   224  * Get the position quality requested by the client.
       
   225  *
       
   226  * @param aRequestedPosQuality The requested position quality.
       
   227  */
       
   228 TInt CPosSubSession::GetRequiredPositionQuality(TPositionQuality& /*aRequestedPosQuality*/) const
       
   229     {
       
   230     DEBUG_TRACE("GetRequiredPositionQuality()", __LINE__)
       
   231 
       
   232     // Not implemented yet.
       
   233     return KErrNotFound;
       
   234     }
       
   235 
       
   236 /**
       
   237  * From MPosParameterObserver.
       
   238  *
       
   239  * Get the earliest allowed time of an old position fix, based on the
       
   240  * current max age set by the client.
       
   241  *
       
   242  * The PSY may save the result from the latest position request and
       
   243  * return the same result in the next position request if the client
       
   244  * says it's ok. Max age tells the PSY how old the stored position is
       
   245  * allowed to be. If the stored position is too old or the PSY does not
       
   246  * support max age, a normal positioning should be performed.
       
   247  *
       
   248  * @param aMaxAge On return, will contain the earliest allowed time of 
       
   249  *   an old position fix. If no max age is defined aMaxAge will contain 
       
   250  *   a time set to zero.
       
   251  */
       
   252 void CPosSubSession::GetMaxAge(TTime& aMaxAge) const
       
   253     {
       
   254     DEBUG_TRACE("GetMaxAge()", __LINE__)
       
   255 
       
   256     if (iMaxUpdateAge != TTimeIntervalMicroSeconds(0))
       
   257         {
       
   258         aMaxAge.UniversalTime();
       
   259         aMaxAge -= iMaxUpdateAge;
       
   260         }
       
   261     else
       
   262         {
       
   263         aMaxAge = TTime(0);
       
   264         }
       
   265     }
       
   266 
       
   267 /**
       
   268  * From MPosParameterObserver.
       
   269  *
       
   270  * Checks if the client allows a partial position update.
       
   271  *
       
   272  * A partial update result does not need to contain all parameters. The
       
   273  * only mandatory parameters are latitude, longitude and time of fix.
       
   274  * Everything else is optional.
       
   275  *
       
   276  * If a partial update is returned to the client in a
       
   277  * NotifyPositionUpdate() call, the completion code must be set to
       
   278  * KPositionPartialUpdate.
       
   279  * 
       
   280  * @return ETrue if partial position updates are allowed, otherwise
       
   281  *   EFalse.
       
   282  */
       
   283 TBool CPosSubSession::IsPartialUpdateAllowed() const
       
   284     {
       
   285     DEBUG_TRACE("IsPartialUpdateAllowed()", __LINE__)
       
   286     return iAcceptPartialUpdates;
       
   287     }
       
   288 
       
   289 /**
       
   290  * Called when a change has occurred in location settings db.
       
   291  * @param aEvent Event information
       
   292  */
       
   293 void CPosSubSession::HandleSettingsChangeL(TPosModulesEvent aEvent)
       
   294     {
       
   295     __ASSERT_DEBUG(iPositionRequest, DebugPanic(EPosServerPanicGeneralInconsistency));
       
   296     iPositionRequest->HandleSettingsChangeL(aEvent);
       
   297     }
       
   298 
       
   299 /**
       
   300  * Called when the server class is shutting down.
       
   301  */
       
   302 void CPosSubSession::NotifyServerShutdown()
       
   303     {
       
   304     DEBUG_TRACE("NotifyServerShutdown", __LINE__)
       
   305     
       
   306     iPositionRequest->NotifyServerShutdown();
       
   307     }
       
   308 
       
   309 void CPosSubSession::HandleSetRequestorL(const RMessage2& aMessage)
       
   310 	{
       
   311     DEBUG_TRACE("EPositionerSetSingleRequestor", __LINE__)
       
   312 
       
   313     // Destroy previously set requestors before any leaving code is called.
       
   314 	// If this method leaves, the requestor array must be empty so any
       
   315 	// subsequent call to NotifyPositionUpdate returns KErrAccessDenied.
       
   316 	iRequestors.ResetAndDestroy();
       
   317 
       
   318 	TPckgBuf<CRequestor::TRequestorType> requestorType;
       
   319     User::LeaveIfError(Global::Read(aMessage, KParamRequestorType, requestorType));
       
   320 
       
   321     // the requestor must be a service
       
   322     if (requestorType() != CRequestor::ERequestorService)
       
   323         {
       
   324         User::Leave(KErrArgument);
       
   325         }
       
   326 
       
   327 	TPckgBuf<CRequestor::TRequestorFormat> requestorFormat;
       
   328     User::LeaveIfError(Global::Read(aMessage, KParamRequestorFormat, requestorFormat));
       
   329 
       
   330     HBufC* data = Global::CopyClientBufferLC(aMessage, KParamRequestorData);
       
   331 
       
   332     CRequestor* requestor = CRequestor::NewLC(requestorType(), requestorFormat(), *data);
       
   333     ValidateRequestorL(requestor);
       
   334     iRequestors.Append(requestor); // takes ownership
       
   335     CleanupStack::Pop(requestor);
       
   336 
       
   337     iPositionRequest->NewTrackingSessionIfTracking();
       
   338     RequestComplete(aMessage, KErrNone);
       
   339 
       
   340     CleanupStack::PopAndDestroy(data);
       
   341 	}
       
   342 
       
   343 void CPosSubSession::HandleSetRequestorStackL(const RMessage2& aMessage)
       
   344 	{
       
   345     DEBUG_TRACE("EPositionerSetMultipleRequestors", __LINE__)
       
   346 
       
   347     // Destroy previously set requestors before any leaving code is called.
       
   348 	iRequestors.ResetAndDestroy();
       
   349 
       
   350     HBufC8* buf = Global::CopyClientBuffer8LC(aMessage, KParamRequestorStack);
       
   351 	RDesReadStream stream(*buf);
       
   352 
       
   353 	iRequestors.InternalizeL(stream);
       
   354 
       
   355 	CleanupStack::PopAndDestroy(buf);
       
   356 
       
   357 	// If this method leaves, the requestor array must be empty so any
       
   358 	// subsequent call to NotifyPositionUpdate returns KErrAccessDenied.
       
   359     TCleanupItem cleanup(ResetAndDestroyRRequestorStack, &iRequestors);
       
   360     CleanupStack::PushL(cleanup);
       
   361 
       
   362     // Last requestor must be a service
       
   363     if (iRequestors.Count() > 0)
       
   364         {
       
   365         CRequestor* last = iRequestors[iRequestors.Count() - 1];
       
   366         if (last->RequestorType() != CRequestor::ERequestorService)
       
   367             {
       
   368             User::Leave(KErrArgument);
       
   369             }
       
   370         }
       
   371     else
       
   372         {
       
   373         User::Leave(KErrArgument);
       
   374         }
       
   375 
       
   376     // validate them all
       
   377     for (TInt i = 0; i < iRequestors.Count(); i++)
       
   378         {
       
   379         ValidateRequestorL(iRequestors[i]);
       
   380         }
       
   381 
       
   382     CleanupStack::Pop(&iRequestors);
       
   383 
       
   384     iPositionRequest->NewTrackingSessionIfTracking();
       
   385 	RequestComplete(aMessage, KErrNone);
       
   386 	}
       
   387 
       
   388 void CPosSubSession::HandleSetUpdateOptionsL(const RMessage2& aMessage)
       
   389     {
       
   390     DEBUG_TRACE("EPositionerSetUpdateOptions", __LINE__)
       
   391 
       
   392     HBufC8* optionsBuf = Global::CopyClientBuffer8LC(aMessage, KParamUpdateOptions);
       
   393     TUint bufferSize = optionsBuf->Size();
       
   394 
       
   395     TPositionUpdateOptionsBase& optionsBase = reinterpret_cast
       
   396         <TPositionUpdateOptionsBase&>(const_cast<TUint8&>(*optionsBuf->Ptr()));
       
   397     
       
   398     // Check update options. Leaves if not accepted values.
       
   399 
       
   400     Global::ValidatePositionClassBufferL(optionsBase, optionsBuf->Des());
       
   401     Global::ValidatePositionClassTypeL(optionsBase, EPositionUpdateOptionsClass);
       
   402 
       
   403     TPositionUpdateOptions& options = 
       
   404         static_cast<TPositionUpdateOptions&>(optionsBase);
       
   405 
       
   406     if ((optionsBase.UpdateTimeOut().Int64() > 0) &&
       
   407         (optionsBase.UpdateInterval() >= optionsBase.UpdateTimeOut()))
       
   408         {
       
   409         User::Leave(KErrArgument);
       
   410         }
       
   411 
       
   412     // Max age must be less than the update interval if both are set.
       
   413 	if (optionsBase.MaxUpdateAge().Int64() != 0 &&
       
   414         optionsBase.UpdateInterval().Int64() != 0 &&
       
   415         optionsBase.MaxUpdateAge() >= optionsBase.UpdateInterval())
       
   416         {
       
   417         User::Leave(KErrArgument);
       
   418         }
       
   419 
       
   420     iTracking = (optionsBase.UpdateInterval().Int64() != 0);
       
   421     iMaxUpdateAge = optionsBase.MaxUpdateAge();
       
   422     iAcceptPartialUpdates = options.AcceptPartialUpdates();
       
   423     iUpdateTimeOut = optionsBase.UpdateTimeOut();
       
   424     
       
   425     if(iUpdateTimeOut==0 && iPsyDefaultUpdateTimeOut>0)
       
   426     	{
       
   427     	optionsBase.SetUpdateTimeOut(iPsyDefaultUpdateTimeOut);
       
   428     	}
       
   429     
       
   430     iPositionRequest->SetUpdateOptions(optionsBase);
       
   431 
       
   432     CleanupStack::PopAndDestroy(optionsBuf);
       
   433     RequestComplete(aMessage, KErrNone);
       
   434     }
       
   435   
       
   436 void CPosSubSession::HandleGetUpdateOptionsL(const RMessage2& aMessage)
       
   437     {    
       
   438     DEBUG_TRACE("EPositionerGetUpdateOptions", __LINE__)
       
   439 
       
   440     HBufC8* optionsBuf = Global::CopyClientBuffer8LC(aMessage, KParamUpdateOptions);
       
   441     TUint bufferSize = optionsBuf->Size();
       
   442 
       
   443     TPositionUpdateOptionsBase& optionsBase = reinterpret_cast
       
   444         <TPositionUpdateOptionsBase&>(const_cast<TUint8&>(*optionsBuf->Ptr()));
       
   445     
       
   446     Global::ValidatePositionClassBufferL(optionsBase, optionsBuf->Des());
       
   447     Global::ValidatePositionClassTypeL(optionsBase, EPositionUpdateOptionsClass);
       
   448 
       
   449     TPositionUpdateOptions& options = static_cast<TPositionUpdateOptions&>(optionsBase);
       
   450 
       
   451     iPositionRequest->GetUpdateOptions(optionsBase);
       
   452     optionsBase.SetMaxUpdateAge(iMaxUpdateAge);
       
   453     options.SetAcceptPartialUpdates(iAcceptPartialUpdates);
       
   454     optionsBase.SetUpdateTimeOut(iUpdateTimeOut);
       
   455     
       
   456     User::LeaveIfError(Global::Write(aMessage, KParamUpdateOptions, *optionsBuf));
       
   457     CleanupStack::PopAndDestroy(optionsBuf);
       
   458     RequestComplete(aMessage, KErrNone);
       
   459     }
       
   460 
       
   461 void CPosSubSession::HandleGetLastKnownPositionL(const RMessage2& aMessage)
       
   462     {
       
   463     DEBUG_TRACE("EPositionerGetLastKnownPosition", __LINE__)
       
   464 
       
   465     if (aMessage.Int1() != EPositionInfoClass)
       
   466     	{
       
   467     	User::Leave(KErrArgument);
       
   468     	}
       
   469    
       
   470     if ( aMessage.Int2() < sizeof(TPositionInfo) )
       
   471     	{
       
   472     	User::Leave(KErrArgument);
       
   473     	}
       
   474 
       
   475     // Request the last known postion area from the CPosLocMonitorReqHandlerHub
       
   476     iLocMonitorReqHandlerHub->GetLastKnownPosReqL(aMessage);
       
   477     }
       
   478 
       
   479 /* Check that a Self-locate is allowed, given the current network roaming status
       
   480 */
       
   481 TBool CPosSubSession::IsSelfLocateEnabled()
       
   482 	{
       
   483 	DEBUG_TRACE("CPositionerSubSession::IsSelfLocateEnabled", __LINE__);
       
   484 	__ASSERT_DEBUG((iAdmin != NULL) && (iLocationManagementSupported != EFalse), DebugPanic(EPosServerPanicGeneralInconsistency));
       
   485 	
       
   486 	TBool selfLocateAllowed(EFalse);
       
   487 	CLbsAdmin::TSelfLocateService serviceStatus(CLbsAdmin::ESelfLocateOff);	
       
   488 	RLbsNetworkRegistrationStatus::TLbsNetworkRegistrationStatus netRegStatus(RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown);
       
   489 	
       
   490 	// Read the current network registration	 status
       
   491 	TInt err = iNetRegStatus.GetNetworkRegistrationStatus(netRegStatus);
       
   492 	if (err == KErrNone)
       
   493 		{
       
   494 		// Read the appropriate admin setting
       
   495 		switch (netRegStatus)
       
   496 			{
       
   497 			case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork:
       
   498 				{
       
   499 				err = iAdmin->Get(KLbsSettingHomeSelfLocate, serviceStatus);
       
   500 				break;
       
   501 				}
       
   502 			case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork:
       
   503 				{
       
   504 				err = iAdmin->Get(KLbsSettingRoamingSelfLocate, serviceStatus);
       
   505 				break;
       
   506 				}		
       
   507 			case RLbsNetworkRegistrationStatus::ENotRegistered:
       
   508 				{
       
   509 				err = iAdmin->Get(KLbsSettingRoamingSelfLocate, serviceStatus);
       
   510 				if(!err && serviceStatus == CLbsAdmin::ESelfLocateOff)
       
   511 					{
       
   512 					// in the case of notregistered we allow selflocate if *either* home or roaming setting is on:
       
   513 					err = iAdmin->Get(KLbsSettingHomeSelfLocate, serviceStatus);
       
   514 					}
       
   515 				}
       
   516 				break;
       
   517 			case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown:
       
   518 			default:
       
   519 				{
       
   520 				serviceStatus = CLbsAdmin::ESelfLocateOff;
       
   521 				break;
       
   522 				}
       
   523 			}
       
   524 		}
       
   525 	
       
   526 	// Check to see if Self Locate is allowed
       
   527 	if (err == KErrNone
       
   528 	    && serviceStatus == CLbsAdmin::ESelfLocateOn)
       
   529 		{
       
   530 		selfLocateAllowed = ETrue;
       
   531 		}
       
   532 	
       
   533 	return selfLocateAllowed;
       
   534 	}
       
   535 
       
   536 void CPosSubSession::HandleNotifyPositionUpdateL(const RMessage2& aMessage)
       
   537     {
       
   538     DEBUG_TRACE("EPositionerNotifyPositionUpdate", __LINE__)
       
   539     
       
   540     // Request cannot be made if one is already in progress
       
   541     //
       
   542     if (iPositionRequest->IsActive())
       
   543         {
       
   544         aMessage.Panic(KPosClientFault, EPositionDuplicateRequest);
       
   545         iPositionRequest->Cancel();
       
   546         return;
       
   547         }
       
   548     else if (iLocationManagementSupported && !IsSelfLocateEnabled())
       
   549     	{
       
   550 		LBS_RDEBUG_ARGTEXT("LBS", "Client", "RunL", "KErrAccessDenied");
       
   551 		aMessage.Complete(KErrAccessDenied); 
       
   552   		return;
       
   553     	}   
       
   554     
       
   555     // Initiate the request
       
   556     iPositionRequest->MakeRequestL(aMessage);
       
   557     }
       
   558 
       
   559 void CPosSubSession::HandleGetLastKnownPositionAreaL(const RMessage2& aMessage)
       
   560 	{
       
   561 	DEBUG_TRACE("ELbsGetLastKnownPositionArea", __LINE__)
       
   562 	
       
   563 	// Request the last known postion area from the CPosLocMonitorReqHandlerHub
       
   564 	iLocMonitorReqHandlerHub->GetLastKnownPosAreaReqL(aMessage);
       
   565 
       
   566 	}
       
   567 
       
   568 void CPosSubSession::HandleGetLastKnownPositionAreaCancelL(const RMessage2& aMessage)
       
   569 	{
       
   570 	DEBUG_TRACE("ELbsGetLastKnownPositionAreaCancelL ", __LINE__)
       
   571 	
       
   572 	iLocMonitorReqHandlerHub->CancelGetLastKnownPosAreaReqL(aMessage);
       
   573 	
       
   574 	}
       
   575 
       
   576 void CPosSubSession::HandleNotifyPositionUpdateCancelL(const RMessage2& aMessage)
       
   577     {
       
   578     DEBUG_TRACE("EPositionerNotifyPositionUpdateCancel", __LINE__)
       
   579 
       
   580     if (!iPositionRequest->IsActive())
       
   581         {
       
   582         User::Leave(KErrNotFound);
       
   583         }
       
   584 
       
   585     iPositionRequest->Cancel();
       
   586     RequestComplete(aMessage, KErrNone);
       
   587     }
       
   588 
       
   589 void CPosSubSession::HandleGetLastKnownPositionCancelL(const RMessage2& aMessage)
       
   590     {
       
   591     DEBUG_TRACE("EPositionerGetLastKnownPositionCancel", __LINE__)
       
   592     iLocMonitorReqHandlerHub->CancelGetLastKnownPosReqL(aMessage);
       
   593     
       
   594     }
       
   595 
       
   596 
       
   597 void CPosSubSession::HandleCancelAsyncRequestL(const RMessage2& aMessage)
       
   598     {
       
   599     switch (aMessage.Int0())
       
   600         {
       
   601         case KGetLastKnownPositionSymbian:
       
   602         case KGetLastKnownPositionVariant:
       
   603         case ELbsGetLastKnownPosition:
       
   604 	        HandleGetLastKnownPositionCancelL(aMessage);
       
   605             break;
       
   606         case KNotifyPositionUpdateSymbian:
       
   607         case KNotifyPositionUpdateVariant:
       
   608         case ELbsPosNotifyPositionUpdate:
       
   609 	        HandleNotifyPositionUpdateCancelL(aMessage);
       
   610             break;
       
   611         case ELbsGetLastKnownPositionArea:					
       
   612         	HandleGetLastKnownPositionAreaCancelL(aMessage);
       
   613         	break;
       
   614         default:
       
   615             User::Leave(KErrNotSupported);
       
   616             break;
       
   617         }
       
   618     }
       
   619 
       
   620 void CPosSubSession::ValidateRequestorL(CRequestor* aRequestor)
       
   621     {
       
   622     // service is identified by application name
       
   623     switch (aRequestor->RequestorType())
       
   624         {
       
   625         case CRequestor::ERequestorService:
       
   626             break;
       
   627         case CRequestor::ERequestorContact:
       
   628             if (aRequestor->RequestorFormat() == CRequestor::EFormatApplication)
       
   629                 {
       
   630                 User::Leave(KErrArgument);
       
   631                 }
       
   632             break;
       
   633         default:
       
   634             User::Leave(KErrArgument); // service or contact is required
       
   635             break;
       
   636         }
       
   637 
       
   638     switch (aRequestor->RequestorFormat())
       
   639         {
       
   640         case CRequestor::EFormatApplication:
       
   641         case CRequestor::EFormatTelephone:
       
   642         case CRequestor::EFormatUrl:
       
   643         case CRequestor::EFormatMail:
       
   644             break;
       
   645         default:
       
   646             User::Leave(KErrArgument); // Unknown or other
       
   647             break;
       
   648         }
       
   649     }
       
   650 
       
   651 void CPosSubSession::RequestComplete(const RMessage2& aMessage, TInt aCompleteCode)
       
   652     {
       
   653     if (!aMessage.IsNull())
       
   654         {
       
   655         aMessage.Complete(aCompleteCode);
       
   656         }
       
   657     }
       
   658 
       
   659 void CPosSubSession::GetUpdateTimeOut(TTimeIntervalMicroSeconds& aUpdateTimeOut) const
       
   660 	{
       
   661 	if(iUpdateTimeOut==0)
       
   662 		{
       
   663 		aUpdateTimeOut = iPsyDefaultUpdateTimeOut;
       
   664 		}
       
   665 	else
       
   666 		{
       
   667 		aUpdateTimeOut = iUpdateTimeOut;
       
   668 		}
       
   669 	}
       
   670 
       
   671 void CPosSubSession::SetPsyDefaultUpdateTimeOut(const TTimeIntervalMicroSeconds& aUpdateTimeOut)
       
   672 	{
       
   673 	iPsyDefaultUpdateTimeOut = aUpdateTimeOut;
       
   674 	
       
   675 	if(iPositionRequest) //It can be zero if this method is called back from CPosSubSession::ConctructL
       
   676 		{
       
   677 		TPositionUpdateOptions updateOptions;
       
   678 		iPositionRequest->GetUpdateOptions(updateOptions);
       
   679 		if(iUpdateTimeOut==0)
       
   680 			{
       
   681 			updateOptions.SetUpdateTimeOut(iPsyDefaultUpdateTimeOut);
       
   682 			iPositionRequest->SetUpdateOptions(updateOptions);
       
   683 			}
       
   684 		}
       
   685 	}
       
   686 
       
   687 void CPosSubSession::ExtendUpdateTimeOut(const TTimeIntervalMicroSeconds& aAdditionalTime)
       
   688 	{
       
   689 	iPositionRequest->ExtendUpdateTimeOut(aAdditionalTime);
       
   690 	}
       
   691 
       
   692 
       
   693