locationrequestmgmt/networkrequesthandler/src/privacyandlocationrequesthandler.cpp
changeset 36 b47902b73a93
child 49 5f20f71a57a3
child 51 95c570bf4a05
equal deleted inserted replaced
35:a2efdd544abf 36:b47902b73a93
       
     1 // Copyright (c) 2006-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 #include <e32std.h>
       
    17 #include <e32property.h>
       
    18 #include <centralrepository.h>
       
    19 
       
    20 #ifdef SYMBIAN_FEATURE_MANAGER
       
    21     #include <featdiscovery.h>
       
    22     #include <featureuids.h>
       
    23 #endif
       
    24 
       
    25 // LBS-specific
       
    26 #include <lbs.h>
       
    27 #include <lbs/lbsadmin.h>
       
    28 #include <lbs/lbslocerrors.h>
       
    29 #include <lbs/lbslocclasstypes.h>
       
    30 
       
    31 #include "nrhpanic.h"
       
    32 #include "lbsdevloggermacros.h"
       
    33 #include "lbsqualityprofile.h"
       
    34 #include "lbsrootcenrepdefs.h"
       
    35 #include "lbspositioningstatusprops.h"
       
    36 
       
    37 #include "privacyandlocationrequesthandler.h"
       
    38 
       
    39 // Special 'invalid session' SessionId.
       
    40 const TLbsNetSessionIdInt KInvalidSessionId(TUid::Uid(0), 0);
       
    41 
       
    42 const TPositionModuleInfo::TTechnologyType KTerminalAssistedMode = (TPositionModuleInfo::ETechnologyNetwork |
       
    43 																	TPositionModuleInfo::ETechnologyAssisted);
       
    44 	
       
    45 // ----------------------------------------------------------------------------- 
       
    46 // 
       
    47 // ----------------------- Class CPrivacyAndLocationHandler --------------------
       
    48 //
       
    49 // State Machine class which owns the states of the Privacy and Location Handler
       
    50 //
       
    51 // ----------------------------------------------------------------------------- 
       
    52 //
       
    53 
       
    54 // ----------------------------------------------------------------------------- 
       
    55 // CPrivacyAndLocationHandler::NewL
       
    56 // Description: CPrivacyAndLocationHandler static constructor 
       
    57 // ----------------------------------------------------------------------------- 
       
    58 //
       
    59 CPrivacyAndLocationHandler* CPrivacyAndLocationHandler::NewL(CNGMessageSwitch& aMessageSwitch,
       
    60 											CLbsAdmin& aLbsAdmin,
       
    61 											RLbsNetworkRegistrationStatus& aNetRegStatus)
       
    62 	{
       
    63 	CPrivacyAndLocationHandler* self; 
       
    64 	self = new (ELeave) CPrivacyAndLocationHandler(aMessageSwitch, aNetRegStatus);
       
    65 	CleanupStack::PushL(self);
       
    66 	self->ConstructL(&aLbsAdmin);
       
    67 	CleanupStack::Pop(self);
       
    68 	return(self);	
       
    69 	}
       
    70 
       
    71 // ----------------------------------------------------------------------------- 
       
    72 // CPrivacyAndLocationHandler::CPrivacyAndLocationHandler
       
    73 // Description: CPrivacyAndLocationHandler constructor 
       
    74 // ----------------------------------------------------------------------------- 
       
    75 //
       
    76 CPrivacyAndLocationHandler::CPrivacyAndLocationHandler(CNGMessageSwitch& aMessageSwitch, 
       
    77 													   RLbsNetworkRegistrationStatus& aNetRegStatus)
       
    78 :	iNetRegStatus(aNetRegStatus),
       
    79 	iMessageSwitch(&aMessageSwitch),
       
    80 	iNumActiveSessions(0)
       
    81 	{	
       
    82 	}
       
    83 	
       
    84 // ----------------------------------------------------------------------------- 
       
    85 // CPrivacyAndLocationHandler::~CPrivacyAndLocationHandler
       
    86 // Description: CPrivacyAndLocationHandler destructor 
       
    87 // ----------------------------------------------------------------------------- 
       
    88 //
       
    89 CPrivacyAndLocationHandler::~CPrivacyAndLocationHandler()
       
    90 	{
       
    91 	// If iEmergencyFsm has been used by any outstanding request,
       
    92 	// it needs to be removed before calling ResetAndDestroy(),
       
    93 	// otherwise it will get double-deleted when delete iEmergencyFsm
       
    94 	// is called.
       
    95 			
       
    96 	TInt index = iFsmArray.Find(iEmergencyFsm);
       
    97 	if (index >= 0)
       
    98 		{
       
    99 		iFsmArray.Remove(index);
       
   100 		}
       
   101 	
       
   102 	iFsmArray.ResetAndDestroy();
       
   103 
       
   104     // force the count of active network initiated positioning sessions to 0
       
   105 	// this supports the pre-APE centric architecture wherein the NRH is
       
   106 	// destroyed on completion of network initiated positioning. 
       
   107     RProperty::Set(iPosStatusCategory, KLbsNiPositioningStatusKey, 0);
       
   108 
       
   109 	delete iEmergencyFsm;
       
   110     delete iAgpsInterface;
       
   111     delete iPrivacyHandler;
       
   112 	}
       
   113 
       
   114 // ----------------------------------------------------------------------------- 
       
   115 // CPrivacyAndLocationHandler::ConstructL
       
   116 // Description: CPrivacyAndLocationHandler second-phase constructor.
       
   117 //              Creates the states of the system and the Privacy Handler.
       
   118 // ----------------------------------------------------------------------------- 
       
   119 //
       
   120 
       
   121 const TInt KLbsDefaultMaxNumLocationRequests   = 4;
       
   122 
       
   123 void CPrivacyAndLocationHandler::ConstructL(CLbsAdmin* aLbsAdmin)
       
   124 	{
       
   125 	iLbsAdmin = aLbsAdmin;
       
   126 	
       
   127 	iPrivacyHandler = CPrivacyHandler::CreateL(this, *iLbsAdmin, iNetRegStatus);
       
   128 	iMessageSwitch->RegisterObserver(this);
       
   129 
       
   130 	// Get the behaviour mode and device gps mode capabilities
       
   131 	TInt err = iLbsAdmin->Get(KLbsSettingBehaviourMode, iLbsBehaviourMode);
       
   132 	if (err != KErrNone)
       
   133 		{
       
   134 		iLbsBehaviourMode = CLbsAdmin::ELbsBehaviourCustom1;
       
   135 		}
       
   136 	// get device mode capabilities:
       
   137 	err = LbsModuleInfo::GetDeviceCapabilities(KLbsGpsLocManagerUid, iDeviceGpsModeCaps);
       
   138 	if(err != KErrNone || (iDeviceGpsModeCaps==TPositionModuleInfoExtended::EDeviceGpsModeNone))
       
   139 		{
       
   140 		// Assume module supports hybrid if it has not reported its capabilities in module info file
       
   141 		iDeviceGpsModeCaps = TPositionModuleInfoExtended::EDeviceGpsModeSimultaneousTATB;
       
   142 		}
       
   143 
       
   144 
       
   145 	err = iLbsAdmin->Get(KLbsSettingMaximumExternalLocateRequests, iMaxNumSessions);
       
   146 	if (err != KErrNone)
       
   147 		{
       
   148 		iMaxNumSessions = KLbsDefaultMaxNumLocationRequests;
       
   149 		}
       
   150 	
       
   151 	iAgpsInterface = CAgpsInterfaceHandler::NewL(*this, *iLbsAdmin, iNetRegStatus);
       
   152 
       
   153 
       
   154 #ifdef NRH_UNIT_TEST
       
   155 	// For testing use the Uid of the dummy NG
       
   156 	const TInt KTestNgUidInt = 0x1028226B;
       
   157 	const TUid KTestNgUid = {KTestNgUidInt};
       
   158 	iProtocolModuleUid = KTestNgUid;
       
   159 #else
       
   160 	ReadProtocolModuleAdminSetting();
       
   161 #endif
       
   162 	
       
   163 	iEmergencyFsm = CLbsPrivLocFsm::NewL(*this, KInvalidSessionId);
       
   164 	
       
   165 	// Reserve space for FSMs. Note "+1" because a pointer to the emergency Fsm gets added to this array
       
   166 	iFsmArray.ReserveL(iMaxNumSessions+1);
       
   167 
       
   168 	CLbsAdmin::TSpecialFeature specialFeature(CLbsAdmin::ESpecialFeatureOff);
       
   169 	err = iLbsAdmin->Get(KLbsSpecialFeatureIntermediateFutileUpdate, specialFeature);
       
   170 	if (err != KErrNone)
       
   171 		{
       
   172 		LBSLOG_ERR2(ELogP3, "Failed to get KLbsSpecialFeatureIntermediateFutileUpdate (err %d)", err);
       
   173 		}
       
   174 	LBSLOG2(ELogP3, "Using KLbsSpecialFeatureIntermediateFutileUpdate = %d", specialFeature);
       
   175 	iSpecialFeatureIntermediateFutileUpdate = (specialFeature == CLbsAdmin::ESpecialFeatureOn) ? ETrue : EFalse;
       
   176 	
       
   177 #ifdef SYMBIAN_FEATURE_MANAGER
       
   178     iLocationManagementSupported = CFeatureDiscovery::IsFeatureSupportedL(NFeature::KLocationManagement);
       
   179 #else
       
   180     __ASSERT_ALWAYS(EFalse, User::Invariant()); // Would happen on older versions of symbian OS if this code ever backported
       
   181 #endif    
       
   182     
       
   183     // Get the CategoryUid from the cenrep file owned by LbsRoot for accessing Positioning Status P&S Keys
       
   184     CRepository* rep = CRepository::NewLC(KLbsCenRepUid);
       
   185     TInt posStatusCategory;
       
   186     err = rep->Get(KNiPositioningStatusAPIKey, posStatusCategory);
       
   187     User::LeaveIfError(err);
       
   188     CleanupStack::PopAndDestroy(rep);
       
   189     iPosStatusCategory = TUid::Uid(posStatusCategory);
       
   190 	}
       
   191 
       
   192 
       
   193 
       
   194 /**
       
   195 Reads the Uid of a current Protocol Module from the Admin Settings.
       
   196 */
       
   197 void CPrivacyAndLocationHandler::ReadProtocolModuleAdminSetting()
       
   198 	{
       
   199 	LBSLOG(ELogP1, "CPrivacyAndLocationHandler::ReadProtocolModuleAdminSetting()");
       
   200 	TLbsProtocolModuleId protUid(KLbsProtocolNullModuleId);
       
   201 	
       
   202 	TInt err = iLbsAdmin->Get(KLbsSettingHomeProtocolModule, protUid);
       
   203 	if (err != KErrNone)
       
   204 		{
       
   205 		LBSLOG_ERR2(ELogP4, "Failed to get KLbsSettingHomeProtocolModule (err %d)", err);
       
   206 		}
       
   207 
       
   208 	iProtocolModuleUid = protUid;
       
   209 	}
       
   210 
       
   211 /** Compares sessionId for RPointerArray::Find().
       
   212 */
       
   213 TBool CPrivacyAndLocationHandler::IsSessionIdEqual(
       
   214 		const TLbsNetSessionIdInt* aSessionId,
       
   215 		const CLbsPrivLocFsm& aFsm)
       
   216 	{
       
   217 	return (*aSessionId == aFsm.SessionId());
       
   218 	}
       
   219 
       
   220 /** Compares session type for RPointerArray::Find().
       
   221 */
       
   222 TBool CPrivacyAndLocationHandler::IsSessionTypeEqual(
       
   223 		const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt* aSessionType,
       
   224 		const CLbsPrivLocFsm& aFsm)
       
   225 	{
       
   226 	return (*aSessionType == const_cast<CLbsPrivLocFsm&>(aFsm).SessionType());
       
   227 	}
       
   228 
       
   229 // ----------------------------------------------------------------------------- 
       
   230 // CPrivacyAndLocationHandler::LookupFsm
       
   231 // Description: Lookup CLbsPrivLocFsm object by session ID.
       
   232 // ----------------------------------------------------------------------------- 
       
   233 //
       
   234 CLbsPrivLocFsm* CPrivacyAndLocationHandler::LookupFsm(const TLbsNetSessionIdInt& aSessionId)
       
   235 	{
       
   236 	LBSLOG2(ELogP3, "LookupFsm session=%d", aSessionId.SessionNum());
       
   237 
       
   238 	// Standard sessions always use the standard state machines.
       
   239 	TInt index = iFsmArray.Find(aSessionId, IsSessionIdEqual);
       
   240 	if (index >= 0)
       
   241 		{
       
   242 		LBSLOG(ELogP3, "LookupFsm: Existing standard FSM found");
       
   243 		return iFsmArray[index];
       
   244 		}
       
   245 	else
       
   246 		{
       
   247 		LBSLOG(ELogP3, "LookupFsm: No standard FSM found");
       
   248 		return NULL;		
       
   249 		}
       
   250 	}
       
   251 
       
   252 /** Get a new state machine to use for a new request.
       
   253 
       
   254 The state machine can either be re-using an existing FSM,
       
   255 or allocating a new one from the heap or, for emergencies one thats was prepared earlier is used.
       
   256 */
       
   257 CLbsPrivLocFsm* CPrivacyAndLocationHandler::GetNewFsm(
       
   258 		const TLbsNetSessionIdInt& aSessionId,
       
   259 		TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType,
       
   260 		TBool aEmergency)
       
   261 	{
       
   262 	LBSLOG2(ELogP3, "LookupFsm session=%d", aSessionId.SessionNum());
       
   263 	
       
   264 	CLbsPrivLocFsm* fsm(NULL);
       
   265 
       
   266 	// If this is an emergency request, use the emergency FSM  
       
   267 	// Note, we only have to support ONE emergency at a time
       
   268 	// this implies that only one Protcol module may deal with emergencies
       
   269 	// So we do NOT support TWO emergencies .. one from each of the PMs
       
   270 	// Note: only MT-LR or NI-LR requests can be emergency requests.
       
   271 	if (aEmergency
       
   272 		&& (aSessionType == MLbsNetworkProtocolObserver::EServiceMobileTerminated
       
   273 		|| aSessionType == MLbsNetworkProtocolObserver::EServiceNetworkInduced))
       
   274 		{					
       
   275 		TInt index = iFsmArray.Find(iEmergencyFsm);
       
   276 		if (index >= 0)
       
   277 			{
       
   278 			iFsmArray.Remove(index);
       
   279 			iNumActiveSessions--;
       
   280 			}
       
   281 		// clean out Fsm
       
   282 		iEmergencyFsm->RefPosProcessed() = EFalse;
       
   283 		iEmergencyFsm->LocReqReceived() = EFalse;
       
   284 		iEmergencyFsm->LocationFixReceived()= EFalse;
       
   285 		iEmergencyFsm->TapMode() = EFalse;
       
   286 		iEmergencyFsm->WasPrivacyResponseReceivedStateExited() = EFalse;
       
   287 		iEmergencyFsm->NetSessionId()= aSessionId;
       
   288 		fsm = iEmergencyFsm;
       
   289 		}
       
   290 	else
       
   291 		{
       
   292 		if (iNumActiveSessions <= iMaxNumSessions)
       
   293 			{
       
   294 			// Create a new session to handle this privacy request
       
   295 			LBSLOG2(ELogP3, "Creating FSM for new standard request %d",aSessionId.SessionNum());
       
   296 			TRAPD(err, fsm = CLbsPrivLocFsm::NewL(*this, aSessionId)); 
       
   297 			if (err != KErrNone)
       
   298 				{
       
   299 				LBSLOG_ERR2(ELogP3, "Failed to create new FSM, error code : %d", err);
       
   300 				}
       
   301 			}
       
   302 		else
       
   303 			{
       
   304 			LBSLOG_ERR3(ELogP3, "Session start rejected! iNumActiveSessions=%d > iMaxNumSessions=%d", iNumActiveSessions, iMaxNumSessions);
       
   305 			}
       
   306 		}
       
   307 
       
   308 	if (fsm)
       
   309 		{
       
   310 		// Add the state machine to the buffer.
       
   311 		iFsmArray.Append(fsm);
       
   312 	
       
   313 		iNumActiveSessions++; // conceptually, a session starts when a Fsm is created for it
       
   314 
       
   315 		}
       
   316 	
       
   317 	return fsm;
       
   318 	}
       
   319 
       
   320 
       
   321 // ----------------------------------------------------------------------------- 
       
   322 // CPrivacyAndLocationHandler::PrivacyHandler
       
   323 // Description: Return a pointer to the privacy handler implementation
       
   324 //              (controller or notifier).
       
   325 // ----------------------------------------------------------------------------- 
       
   326 //
       
   327 CPrivacyHandler* CPrivacyAndLocationHandler::PrivacyHandler()
       
   328 	{
       
   329 	return iPrivacyHandler;
       
   330 	}
       
   331 	
       
   332 // ----------------------------------------------------------------------------- 
       
   333 // CPrivacyAndLocationHandler::MessageSwitch
       
   334 // Description: Return a pointer to the Network Gateway Message Switch
       
   335 // ----------------------------------------------------------------------------- 
       
   336 //
       
   337 CNGMessageSwitch* CPrivacyAndLocationHandler::MessageSwitch()
       
   338 	{
       
   339 	return iMessageSwitch;
       
   340 	}
       
   341 	
       
   342 // ----------------------------------------------------------------------------- 
       
   343 // CPrivacyAndLocationHandler::LbsAdmin
       
   344 // Description: Return a pointer to the Admin settings database
       
   345 // ----------------------------------------------------------------------------- 
       
   346 //
       
   347 CLbsAdmin* CPrivacyAndLocationHandler::LbsAdmin()
       
   348 	{
       
   349 	return iLbsAdmin;
       
   350 	}
       
   351 	
       
   352 // ----------------------------------------------------------------------------- 
       
   353 // CPrivacyAndLocationHandler::SetServerObserver
       
   354 // Description: Store a pointer to the NRH server which comunicates with the 
       
   355 // Privacy Controller.
       
   356 // ----------------------------------------------------------------------------- 
       
   357 //
       
   358 void CPrivacyAndLocationHandler::SetServerObserver(MLbsSessionObserver* aNrhServer)
       
   359     {
       
   360     PrivacyHandler()->SetServerObserver(aNrhServer);
       
   361     }
       
   362 
       
   363 // ----------------------------------------------------------------------------- 
       
   364 // CPrivacyAndLocationHandler::OnRespondNetworkLocationRequest
       
   365 // Description: Called by the Privacy Handler to report the result of a privacy
       
   366 // check. Handling of the response is delegated to the current state.
       
   367 // ----------------------------------------------------------------------------- 
       
   368 //
       
   369 void CPrivacyAndLocationHandler::OnRespondNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId, 
       
   370                             TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult,
       
   371                             TInt aResponseReason)
       
   372 	{
       
   373 	LBSLOG2(ELogP3, "Received response %d to privacy request", aRequestResult);
       
   374 	CLbsPrivLocFsm* fsm = LookupFsm(aRequestId);
       
   375 	
       
   376 	if (NULL != fsm)
       
   377 		{
       
   378 		fsm->OnRespondNetworkLocationRequest(aRequestId, aRequestResult, aResponseReason);
       
   379 		}
       
   380 	else
       
   381 		{
       
   382 		LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id");
       
   383 		}
       
   384     }
       
   385 
       
   386 // ----------------------------------------------------------------------------- 
       
   387 // CPrivacyAndLocationHandler::OnCancelNetworkLocationRequest
       
   388 // Description: Called by the Privacy Handler to report that a privacy check 
       
   389 // has been rejected. This may occur after it has already been accepted.
       
   390 // Handling of the response is delegated to the current state.
       
   391 // ----------------------------------------------------------------------------- 
       
   392 //
       
   393 void CPrivacyAndLocationHandler::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId)
       
   394     {
       
   395 	LBSLOG2(ELogP3, "Received cancellation to privacy request %d", aRequestId.SessionNum());
       
   396 	CLbsPrivLocFsm* fsm = LookupFsm(aRequestId);
       
   397 	
       
   398 	if (NULL != fsm)
       
   399 		{
       
   400 		fsm->OnCancelNetworkLocationRequest(aRequestId);
       
   401 		}
       
   402 	else
       
   403 		{
       
   404 		LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id");
       
   405 		}
       
   406     }
       
   407 
       
   408 // ----------------------------------------------------------------------------- 
       
   409 // CPrivacyAndLocationHandler::OnMTLRRequest
       
   410 // Description: The Message Switch has forwarded a request to start an MTLR 
       
   411 // session.
       
   412 // Handling of the request is delegated to the current state.
       
   413 // ----------------------------------------------------------------------------- 
       
   414 //
       
   415 void CPrivacyAndLocationHandler::OnMTLRRequest(const TLbsNetSessionIdInt& aSessionId,
       
   416 					   TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
   417 					   TBool aIsEmergency,
       
   418 					   const TLbsExternalRequestInfo& aExternalRequestInfo,
       
   419 					   const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy)
       
   420 	{
       
   421 	LBSLOG2(ELogP3, "Received privacy request with id %d", aSessionId.SessionNum());
       
   422 	CLbsPrivLocFsm* fsm = LookupFsm(aSessionId);
       
   423 
       
   424 	if (fsm==NULL)
       
   425 		{
       
   426 		fsm = GetNewFsm(aSessionId, aSessionType, aIsEmergency);
       
   427 		}
       
   428 	
       
   429 	if (NULL != fsm)
       
   430 		{
       
   431 		fsm->OnMTLRRequest(aSessionId, 
       
   432 						   aSessionType, 
       
   433 						   aIsEmergency, 
       
   434 						   aExternalRequestInfo, 
       
   435 						   aNetPosRequestPrivacy);
       
   436 		}
       
   437 	else
       
   438 		{					
       
   439 		// Failed to create a state machine for this request,
       
   440 		// so simply reply with a privacy rejection.
       
   441 		iMessageSwitch->SendMTLRResponse(aSessionId, 
       
   442 										 TLbsNetworkEnumInt::EPrivacyResponseRejected,
       
   443 										 KErrGeneral, EFalse); // can't be an emergency cuase we know we have a Fsm for these!
       
   444 		}
       
   445 	}
       
   446 	
       
   447 // ----------------------------------------------------------------------------- 
       
   448 // CPrivacyAndLocationHandler::OnSessionComplete
       
   449 // Description: The Message Switch has reported that the session is
       
   450 // over (complete or aborted due to some error).
       
   451 // Handling of the message is delegated to the current state.
       
   452 // ----------------------------------------------------------------------------- 
       
   453 //
       
   454 void CPrivacyAndLocationHandler::OnSessionComplete(
       
   455 									const TLbsNetSessionIdInt& aSessionId,
       
   456 									TInt aReason)
       
   457 	{
       
   458 	LBSLOG3(ELogP3, "Received Session Complete for id %d, reason %d", aSessionId.SessionNum(), aReason);
       
   459 	CLbsPrivLocFsm* fsm = LookupFsm(aSessionId);
       
   460 	
       
   461 	if (NULL != fsm)
       
   462 		{
       
   463 		fsm->OnSessionComplete(aSessionId, aReason);
       
   464 
       
   465 		// The session complete marks the end of a session.
       
   466 		TInt index = iFsmArray.Find(fsm);
       
   467 		if (index != KErrNotFound)
       
   468 			{ 
       
   469 			
       
   470 			if (fsm->SessionType()== TLbsNetworkEnumInt::EServiceSelfLocation)
       
   471 				{
       
   472 				iMolRFsm = NULL;
       
   473 				}
       
   474 			else if (fsm->SessionType()== TLbsNetworkEnumInt::EServiceTransmitThirdParty)
       
   475 				{
       
   476 				iX3pFsm = NULL;
       
   477 				}
       
   478 			
       
   479 			// We should never delete the emergency FSM.
       
   480 			iFsmArray.Remove(index);
       
   481 			iNumActiveSessions--;
       
   482 			
       
   483 			if (fsm != iEmergencyFsm)
       
   484 				{
       
   485 				delete fsm;
       
   486 				}
       
   487 			}
       
   488 		}
       
   489 	else
       
   490 		{
       
   491 		LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id");
       
   492 		}
       
   493 	}
       
   494 
       
   495 // ----------------------------------------------------------------------------- 
       
   496 // CPrivacyAndLocationHandler::OnNetLocRequest
       
   497 // Description: The Message Switch has passed on a request for a position update
       
   498 // Handling of the request is delegated to the current state.
       
   499 // ----------------------------------------------------------------------------- 
       
   500 //
       
   501 void CPrivacyAndLocationHandler::OnNetLocRequest(
       
   502 						const TLbsNetSessionIdInt& aSessionId, 
       
   503 						const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
   504 						TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
   505 						TBool aIsEmergency,
       
   506 						const TLbsNetPosRequestQualityInt& aQuality)
       
   507 	{
       
   508 	LBSLOG2(ELogP3, "Received position update request for id %d", aSessionId.SessionNum());
       
   509 	
       
   510 	TLbsNetSessionIdInt sessionId;
       
   511 	TPositionInfo    posInfo;
       
   512 	TPosition		 pos;
       
   513 	TTime 			 timeStamp;
       
   514 	TInt 			 err;
       
   515 	
       
   516 	TBool tapMode = EFalse;
       
   517 	TInt numMethods = aPosRequestMethod.NumPosMethods();
       
   518     if (numMethods==1)
       
   519     	{
       
   520     	TLbsNetPosMethodInt netPosMethod;
       
   521     	aPosRequestMethod.GetPosMethod(0,netPosMethod);
       
   522                  
       
   523     	if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted))
       
   524     		{
       
   525     		tapMode = ETrue;
       
   526     		}
       
   527     	}
       
   528 	
       
   529 	// This filtering used to be in the NG Message Switch, but has been moved
       
   530 	// here to get an access to the ref position bus
       
   531 	
       
   532 	if( (aSessionType == TLbsNetworkEnumInt::EServiceNetworkLocation) && !tapMode)
       
   533 		{
       
   534 		// A Network-based location request generates a location 
       
   535 		// request to the network request handler, but there's no point 
       
   536 		// passing it any further - the AGPS manager & privacy 
       
   537 		// controller aren't interested.
       
   538 		// Simply return the saved reference location
       
   539 		err = iMessageSwitch->GetNetworkReferencePosition(aSessionId, posInfo);			
       
   540 		posInfo.GetPosition(pos);
       
   541 		timeStamp = pos.Time();
       
   542 		TLbsNetPosRequestQualityInt dummyQuality;
       
   543 		MessageSwitch()->SendNetLocResponse(aSessionId, err, dummyQuality, posInfo, timeStamp, EFalse);
       
   544 		}
       
   545 	else
       
   546 		{
       
   547 		// we note that a self locate MoLr session can be implicitly
       
   548 		// cancelled by the start of a new session for a new client.
       
   549 		// In this case we complete the session before creating a new
       
   550 		// fsm for the new client 
       
   551 		CLbsPrivLocFsm* fsm = LookupFsm(aSessionId);
       
   552 		if (!fsm)
       
   553 			{
       
   554 			// here, we need to create a new fsm
       
   555 			// We note that only one self locate MolR (or X3p) is supported
       
   556 			// a new one will implicitly cancel any ongoing
       
   557 			if(aSessionType == TLbsNetworkEnumInt::EServiceSelfLocation)
       
   558 				{
       
   559 				if (iMolRFsm)
       
   560 					{
       
   561 					TInt index = iFsmArray.Find(iMolRFsm);
       
   562 					if (index != KErrNotFound)
       
   563 						{ 
       
   564 						iFsmArray.Remove(index);
       
   565 						iNumActiveSessions--;
       
   566 						delete iMolRFsm;
       
   567 						iMolRFsm = NULL;
       
   568 						}
       
   569 					}
       
   570 					
       
   571 				}
       
   572 			else if(aSessionType == TLbsNetworkEnumInt::EServiceTransmitThirdParty)
       
   573 				{
       
   574 				if (iX3pFsm)
       
   575 					{
       
   576 					TInt index = iFsmArray.Find(iX3pFsm);
       
   577 					if (index != KErrNotFound)
       
   578 						{ 
       
   579 						iFsmArray.Remove(index);
       
   580 						iNumActiveSessions--;
       
   581 						delete iX3pFsm;
       
   582 						iX3pFsm = NULL;
       
   583 						}
       
   584 					}
       
   585 				}
       
   586 				
       
   587 			fsm = GetNewFsm(aSessionId, aSessionType, aIsEmergency);
       
   588 			}
       
   589 		
       
   590 		if (NULL != fsm)
       
   591 			{
       
   592 			if(aSessionType == TLbsNetworkEnumInt::EServiceSelfLocation)
       
   593 				{
       
   594 				iMolRFsm = fsm;
       
   595 				}
       
   596 			else if(aSessionType == TLbsNetworkEnumInt::EServiceTransmitThirdParty)
       
   597 				{
       
   598 				iX3pFsm = fsm;
       
   599 				}
       
   600 			
       
   601 			fsm->OnNetLocRequest(aSessionId,
       
   602 					aPosRequestMethod, 
       
   603 			 					aSessionType, 
       
   604 								aIsEmergency, 
       
   605 								aQuality);
       
   606 			}			
       
   607 		else
       
   608 			{
       
   609 			// TODO: Return a dummy loc response with error code?
       
   610 			LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id");
       
   611 			}
       
   612 		}
       
   613 	}
       
   614 
       
   615 /** Called when a reference position arrives from the network.
       
   616 */
       
   617 void CPrivacyAndLocationHandler::OnNetLocReferenceUpdate(
       
   618 		const TLbsNetSessionIdInt& aSessionId, 
       
   619 		const TPositionInfoBase& aPosInfo)
       
   620 	{
       
   621 	LBSLOG2(ELogP3, "Received reference position update for id %d", aSessionId.SessionNum());
       
   622 	CLbsPrivLocFsm* fsm = LookupFsm(aSessionId);
       
   623 	
       
   624 	if (NULL != fsm)
       
   625 		{
       
   626 		fsm->OnNetLocReferenceUpdate(aSessionId, aPosInfo);
       
   627 		}
       
   628 	else
       
   629 		{
       
   630 		LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id");
       
   631 		}	
       
   632 	}
       
   633 
       
   634 /** Callend when a final location arrives from the network.
       
   635 */
       
   636 void CPrivacyAndLocationHandler::OnNetLocFinalUpdate(
       
   637 		const TLbsNetSessionIdInt& aSessionId, 
       
   638 		const TPositionInfoBase& aPosInfo)
       
   639 	{
       
   640 	LBSLOG2(ELogP3, "Received final network position update for id %d", aSessionId.SessionNum());
       
   641 	CLbsPrivLocFsm* fsm = LookupFsm(aSessionId);
       
   642 	
       
   643 	if (NULL != fsm)
       
   644 		{
       
   645 		fsm->OnNetLocFinalUpdate(aSessionId, aPosInfo);
       
   646 		}
       
   647 	else
       
   648 		{
       
   649 		LBSLOG_WARN(ELogP3, "Couldn't find a FSM with matching session Id");
       
   650 		}
       
   651 	}
       
   652 
       
   653 /** Callback when a GPS position update arrives from AGPS manager.
       
   654 */
       
   655 void CPrivacyAndLocationHandler::OnAgpsPositionUpdate(
       
   656 	TInt aReason,
       
   657 	const TPositionExtendedSatelliteInfo& aPosInfo,
       
   658 	const TTime& aTimeStamp)
       
   659 	{
       
   660 	// Broadcast the update to all state machines.
       
   661 	const TInt count = iFsmArray.Count();
       
   662 	for (TInt i = 0; i < count; i++)
       
   663 		{
       
   664 		iFsmArray[i]->OnAgpsPositionUpdate(aReason, aPosInfo, aTimeStamp);
       
   665 		}
       
   666 	}
       
   667 
       
   668 /** Callback when a GPS measurement results update arrives from AGPS manager.
       
   669 */
       
   670 void CPrivacyAndLocationHandler::OnAgpsMeasurementUpdate(
       
   671 	TInt aReason,
       
   672 	const TPositionGpsMeasurementInfo& aPosInfo,
       
   673 	const TTime& aTimeStamp)
       
   674 	{
       
   675 	// Broadcast the update to all state machines
       
   676 	const TInt count = iFsmArray.Count();
       
   677 	for (TInt i = 0; i < count; i++)
       
   678 		{
       
   679 		iFsmArray[i]->OnAgpsMeasurementUpdate(aReason, aPosInfo, aTimeStamp);
       
   680 		}
       
   681 	}
       
   682 
       
   683 /**
       
   684 */
       
   685 CAgpsInterfaceHandler* CPrivacyAndLocationHandler::AgpsHandler()
       
   686 	{
       
   687 	return iAgpsInterface;
       
   688 	}
       
   689 	
       
   690 // -----------------------------------------------------------------------------
       
   691 // CPrivacyAndLocationHandler::DeviceGpsModeCaps
       
   692 // Description: Return the device mode capabilities
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 TPositionModuleInfoExtended::TDeviceGpsModeCapabilities CPrivacyAndLocationHandler::DeviceGpsModeCaps()
       
   696 	{
       
   697 	return iDeviceGpsModeCaps;
       
   698 	}
       
   699 
       
   700 // -----------------------------------------------------------------------------
       
   701 // CPrivacyAndLocationHandler::BehaviourMode
       
   702 // Description: Return the behaviour mode setting
       
   703 // -----------------------------------------------------------------------------
       
   704 //
       
   705 CLbsAdmin::TLbsBehaviourMode CPrivacyAndLocationHandler::BehaviourMode()
       
   706 	{
       
   707 	return iLbsBehaviourMode;
       
   708 	}
       
   709 
       
   710 RLbsNetworkRegistrationStatus& CPrivacyAndLocationHandler::NetworkRegistrationStatus()
       
   711 	{
       
   712 	return iNetRegStatus;
       
   713 	}
       
   714 
       
   715 // increments the P&S key tracking mobile terminated positioning requests
       
   716 void CPrivacyAndLocationHandler::IncrementPositioningStatus()
       
   717     {
       
   718     TInt count;     
       
   719     RProperty::Get(iPosStatusCategory, KLbsNiPositioningStatusKey, count);
       
   720     RProperty::Set(iPosStatusCategory, KLbsNiPositioningStatusKey, count+1);
       
   721     }
       
   722 
       
   723 // decrements the P&S key tracking mobile terminated positioning requests
       
   724 // if location management is supported. In the alternative architecture,
       
   725 // the NRH is not aware of the positioning session's progress, but is 
       
   726 // transient. Therefore the positioning status is set to zero in the 
       
   727 // class destructor.
       
   728 void CPrivacyAndLocationHandler::DecrementPositioningStatus()
       
   729     {
       
   730     if (iLocationManagementSupported)
       
   731         {
       
   732         TInt count;     
       
   733         RProperty::Get(iPosStatusCategory, KLbsNiPositioningStatusKey, count);
       
   734         if(count>0)
       
   735             {
       
   736             RProperty::Set(iPosStatusCategory, KLbsNiPositioningStatusKey, count-1);
       
   737             }
       
   738         else
       
   739             {
       
   740             LBSLOG_ERR(ELogP3, "CPrivacyAndLocationHandler::DecrementPositioningStatus() - Incorrect Positioning Status count\n");
       
   741             }
       
   742         }
       
   743     }
       
   744 	
       
   745 
       
   746 /**
       
   747 */
       
   748 MX3pStatusHandler& CPrivacyAndLocationHandler::X3pStatusHandler()
       
   749 	{
       
   750 	return *iAgpsInterface;
       
   751 	}
       
   752 
       
   753 /** Returns ETrue if KLbsSpecialFeatureIntermediateFutileUpdate is on.
       
   754 @return ETrue if the special feature is on, EFalse otherwise.
       
   755 */
       
   756 TBool CPrivacyAndLocationHandler::IsSpecialFeatureIntermediateFutileUpdateOn()
       
   757 	{
       
   758 	return iSpecialFeatureIntermediateFutileUpdate;
       
   759 	}
       
   760 
       
   761 // ----------------------------------------------------------------------------- 
       
   762 // 
       
   763 // ----------------------- Class CLbsPrivLocStateBase --------------------
       
   764 //
       
   765 // This class is not intended for instantiation. Implemented functions are
       
   766 // those common to multiple derived states
       
   767 //
       
   768 // ----------------------------------------------------------------------------- 
       
   769 //
       
   770 
       
   771 // ----------------------------------------------------------------------------- 
       
   772 // CLbsPrivLocStateBase::OnCancelNetworkLocationRequest
       
   773 // Description: Pass on a received privacy request cancel to the network gateway, 
       
   774 // if it relates to the current session. 
       
   775 // This behaviour is common to states EStateWaitLocationRequest,
       
   776 // EStateWaitLocationUpdate and EStateWaitPrivacyResponse.
       
   777 // Other states ignore the event.
       
   778 // ----------------------------------------------------------------------------- 
       
   779 //
       
   780 void CLbsPrivLocStateBase::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aSessionId)
       
   781 	{
       
   782 	/* Ignore the cancel if this is an emergency request */
       
   783 	if(!iFsm->IsEmergency())
       
   784 		{
       
   785 		// Also ignore it if the cancel doesn't relate to this session.
       
   786 		if(aSessionId == iFsm->SessionId())
       
   787 			{
       
   788 			iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitCancelledByPrivacyController, KErrCancel);
       
   789 			iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId);
       
   790 			}
       
   791 		}
       
   792 	}
       
   793 
       
   794 // ----------------------------------------------------------------------------- 
       
   795 // CLbsPrivLocStateBase::OnEntry
       
   796 // Description: Handles initialisation actions which are common to multiple states. 
       
   797 // ----------------------------------------------------------------------------- 
       
   798 //
       
   799 void CLbsPrivLocStateBase::OnEntry(const TPrivLocCommonParams& /* aStateParams */)
       
   800 	{
       
   801 	// Exit reason should always be explicitly set by a state, 
       
   802 	// otherwise OnExit() will panic
       
   803 	iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitReasonNone, KErrNone);
       
   804 	}
       
   805 	
       
   806 	
       
   807 // ----------------------------------------------------------------------------- 
       
   808 // CLbsPrivLocStateBase::OnExit
       
   809 // Description: Handles exit actions which are common to multiple states. 
       
   810 // Any exit reason not handled here is delegated to the current state.
       
   811 // ----------------------------------------------------------------------------- 
       
   812 //
       
   813 TBool CLbsPrivLocStateBase::OnExit()
       
   814 	{
       
   815 	TBool consumed = ETrue;
       
   816 	switch(iFsm->iExitData.iExitReason)
       
   817 		{
       
   818 		case TPrivLocStateExitData::EExitSessionComplete:
       
   819 			{
       
   820 			// Tell the AGPS interface handle this location request has finished.
       
   821 			AgpsInterface()->StopPositioning(iFsm->SessionId());
       
   822 
       
   823 			// Tell the privacy controller this session is finished.
       
   824 			PrivacyHandler()->ProcessRequestComplete(iFsm->SessionId(),
       
   825 													 iFsm->ExitData().iExitInfo);
       
   826 			break;
       
   827 			}
       
   828 
       
   829 		case TPrivLocStateExitData::EExitCancelledByPrivacyController:
       
   830 			{
       
   831 			// Send a cancel to the network gateway
       
   832 			TPositionInfo dummyPosInfo;
       
   833 			TTime dummyTime;
       
   834 			TLbsNetPosRequestQualityInt dummyQuality;
       
   835 			MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
   836 												iFsm->ExitData().iExitInfo,
       
   837 												dummyQuality,
       
   838 												dummyPosInfo,
       
   839 												dummyTime,
       
   840 												iFsm->IsEmergency());
       
   841 			}
       
   842 			break;
       
   843 
       
   844 		case TPrivLocStateExitData::EExitLocReqReceived:
       
   845 			// No action required - request is issued on entry to next state.
       
   846 		case TPrivLocStateExitData::EExitPrivacyRequestReceived:
       
   847 			// No action required, state moves to waiting for loc request.
       
   848 			{
       
   849 			consumed = ETrue;
       
   850 			break;			
       
   851 			}
       
   852 			
       
   853 		default:
       
   854 			{
       
   855 			// Don't know what to do with it.
       
   856 			consumed = EFalse;
       
   857 			break;							
       
   858 			}
       
   859 		}
       
   860 	return(consumed);
       
   861 	}
       
   862 	
       
   863 // ----------------------------------------------------------------------------- 
       
   864 // CLbsPrivLocStateBase::HandleLocRequest
       
   865 // Description: Common handling of a location request received while the 
       
   866 // Privacy and Location Handler is dealing with a session.
       
   867 // 
       
   868 // If the session type is anything but MTLR, then it is processed, otherwise
       
   869 // a privacy request is generated
       
   870 // ----------------------------------------------------------------------------- 
       
   871 //
       
   872 void CLbsPrivLocStateBase::HandleLocRequest(const TLbsNetSessionIdInt& aSessionId, 
       
   873 						 const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
   874 						 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
   875 						 TBool aIsEmergency,
       
   876 						 const TLbsNetPosRequestQualityInt& aQuality)
       
   877 	{
       
   878 	// MTLR.
       
   879 	if (aSessionType == TLbsNetworkEnumInt::EServiceMobileTerminated)
       
   880 		{
       
   881 		// An MTLR with out a prior privacy request is not supported, report error via
       
   882 		// RespondLocationRequest(dummy position).
       
   883 		TPositionInfo dummyPosInfo;
       
   884 		TTime dummyTime;
       
   885 		TLbsNetPosRequestQualityInt dummyQuality;
       
   886 
       
   887 		MessageSwitch()->SendNetLocResponse(aSessionId,
       
   888 											KErrNotSupported,
       
   889 											dummyQuality,
       
   890 											dummyPosInfo,
       
   891 											dummyTime, aIsEmergency); 
       
   892 		}
       
   893 
       
   894 	// Network Induced.	
       
   895 	else if (aSessionType == TLbsNetworkEnumInt::EServiceNetworkInduced)
       
   896 		{
       
   897 		// If a request for a position update has been received without
       
   898 		// a privacy request, then there's nothing to say how the user
       
   899 		// should be informed or what do do if there is no response.
       
   900 		// The safest thing is to get the user to confirm (verify)
       
   901 		// the request, and in the absence of confirmation to reject the
       
   902 		// request. For emergency requests we notify and accept.
       
   903 		
       
   904 		// Store the loc req.
       
   905 		iFsm->LocReqReceived() = ETrue;
       
   906 
       
   907 		iFsm->IsEmergency() = aIsEmergency;
       
   908 		iFsm->NetRequestQuality() = aQuality;
       
   909 		iFsm->PosRequestMethod() = aPosRequestMethod;
       
   910 
       
   911 
       
   912 		// The following notification types are chosen based on the emergency and network requests admin status.
       
   913 		//
       
   914 		// Emergency = On, Admin = Any, gives ENotifyLocationAccepted 
       
   915 		// Emergency = Off,	Admin = On, gives ENotifyLocationAccepted
       
   916 		// Emergency = Off,	Admin = OnButAlwayVerify, gives ENotifyAndVerifyLocationRejectedIfNoResponse
       
   917 		// Emergency = Off, Admin = Off, N/A the notifier or controller will not be called
       
   918 		// Emergency = Off, Admin = OffButNotify, gives ENotifyLocationRejected
       
   919 		TLbsNetPosRequestPrivacyInt requestPrivacy;
       
   920 		
       
   921 		requestPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceNotify);
       
   922 		requestPrivacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionAllow);
       
   923 
       
   924 		// Verifications are rejected after timeout.
       
   925 		CLbsAdmin::TExternalLocateService externalLocate(CLbsAdmin::EExternalLocateOff);
       
   926 
       
   927 		ReadNetworkInducedAdminSetting(externalLocate);
       
   928 		if ((externalLocate == CLbsAdmin::EExternalLocateOnButAlwaysVerify) && (!aIsEmergency))
       
   929 			{
       
   930 	    	requestPrivacy.SetRequestAdvice(TLbsNetPosRequestPrivacyInt::ERequestAdviceVerify);
       
   931 	    	requestPrivacy.SetRequestAction(TLbsNetPosRequestPrivacyInt::ERequestActionReject);
       
   932 			}
       
   933 
       
   934 		// Similarly, default values have to be assigned to the external request info.
       
   935 		TLbsExternalRequestInfo requestInfo;
       
   936 		_LIT8(KUnknownExternalReqInfoField, "");
       
   937 		requestInfo.SetRequesterId(KUnknownExternalReqInfoField);
       
   938 		requestInfo.SetClientName(KUnknownExternalReqInfoField);
       
   939 		requestInfo.SetClientExternalId(KUnknownExternalReqInfoField);
       
   940 
       
   941 
       
   942 		// Process the privacy request.		
       
   943 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone);
       
   944 		
       
   945 		TPrivLocWaitPrivResponseParams privacyRequestParams(aSessionId, aSessionType, requestInfo, requestPrivacy, aIsEmergency);
       
   946 		iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitPrivacyResponse, privacyRequestParams);
       
   947 		}
       
   948 	
       
   949 	// All other location requests.
       
   950 	else
       
   951 		{
       
   952 		TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId,
       
   953 															aPosRequestMethod,
       
   954 															aSessionType,
       
   955 															aIsEmergency,
       
   956 															aQuality);
       
   957 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, KErrCancel);
       
   958 		iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams);
       
   959 		}
       
   960 	}
       
   961 
       
   962 // ----------------------------------------------------------------------------- 
       
   963 // CLbsPrivLocStateBase::OnSessionComplete
       
   964 // Description: Common handling of a session complete message received other
       
   965 // than when it is expected as normal session completion.
       
   966 // ----------------------------------------------------------------------------- 
       
   967 //
       
   968 void CLbsPrivLocStateBase::OnSessionComplete(const TLbsNetSessionIdInt& aSessionId,
       
   969 																TInt aReason)
       
   970 	{
       
   971 	if(aSessionId == iFsm->SessionId())
       
   972 		{
       
   973 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, aReason);
       
   974 		iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId);
       
   975 		}		
       
   976 	}
       
   977 
       
   978 /** Called when a reference position arrives from the network.
       
   979 */
       
   980 void CLbsPrivLocStateBase::OnNetLocReferenceUpdate(
       
   981 		const TLbsNetSessionIdInt& /*aSessionId*/ , 
       
   982 		const TPositionInfoBase& aPosInfo)
       
   983 	{
       
   984 	TLbsNetworkEnumInt::TLbsNetProtocolServiceInt sessionType = iFsm->SessionType();
       
   985 	__ASSERT_DEBUG((sessionType != MLbsNetworkProtocolObserver::EServiceNone), Panic(ENrhPanicBadParamType));
       
   986 
       
   987 	if( ((sessionType == MLbsNetworkProtocolObserver::EServiceNetworkInduced) || 
       
   988 											   (sessionType == MLbsNetworkProtocolObserver::EServiceMobileTerminated)))
       
   989 		{
       
   990 		TPositionInfo posInfo = static_cast<const TPositionInfo&>(aPosInfo);
       
   991 		
       
   992 		// Set the module Id and position mode for the reference position.
       
   993 		// These values are not 'real' values, since this position
       
   994 		// came directly from the network and not one of the location
       
   995 		// managers within LBS.
       
   996 		posInfo.SetModuleId(KLbsGpsLocManagerUid);
       
   997 		posInfo.SetPositionMode(TPositionModuleInfo::ETechnologyNetwork);
       
   998 		posInfo.SetPositionModeReason(EPositionModeReasonNone);
       
   999 		posInfo.SetUpdateType(EPositionUpdateGeneral);
       
  1000 		
       
  1001 		if (!iFsm->RefPosProcessed())
       
  1002 			{
       
  1003 			iFsm->RefPosProcessed() = ETrue;
       
  1004 			PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), posInfo);
       
  1005 			}
       
  1006 
       
  1007 		}	
       
  1008 	}
       
  1009 
       
  1010 /* Timer callback called when the MaxFixTime for a gps location update request has expired. 
       
  1011 
       
  1012 The default action is to ignore this callback. Any state interested in it must
       
  1013 implement its own version.
       
  1014 */
       
  1015 void CLbsPrivLocStateBase::OnTimerEventL(TInt /*aTimerId*/)
       
  1016 	{
       
  1017 	}
       
  1018 
       
  1019 
       
  1020 // ----------------------------------------------------------------------------- 
       
  1021 // CLbsPrivLocStateBase::ReadNetworkInducedAdminSetting
       
  1022 // Description: Determine the external location value from the admin settings for network induced location requests.
       
  1023 // ----------------------------------------------------------------------------- 
       
  1024 //
       
  1025 void CLbsPrivLocStateBase::ReadNetworkInducedAdminSetting(CLbsAdmin::TExternalLocateService& aExternalLocateService)
       
  1026 	{
       
  1027 	CLbsAdmin::TExternalLocateService serviceStatus(CLbsAdmin::EExternalLocateOff);
       
  1028 	RLbsNetworkRegistrationStatus::TLbsNetworkRegistrationStatus netRegStatus(RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown);	
       
  1029 	TInt err = LbsNetworkRegistrationStatus().GetNetworkRegistrationStatus(netRegStatus);
       
  1030 	if (err == KErrNone)
       
  1031 		{
       
  1032 		switch (netRegStatus)
       
  1033 			{
       
  1034 			case RLbsNetworkRegistrationStatus::ERegisteredHomeNetwork:
       
  1035 				{
       
  1036 				err = LbsAdmin()->Get(KLbsSettingHomeNetworkInducedLocate, serviceStatus);
       
  1037 				break;
       
  1038 				}
       
  1039 			case RLbsNetworkRegistrationStatus::ERegisteredRoamingNetwork:
       
  1040 			case RLbsNetworkRegistrationStatus::ENotRegistered:
       
  1041 				{
       
  1042 				err = LbsAdmin()->Get(KLbsSettingRoamingNetworkInducedLocate, serviceStatus);
       
  1043 				break;
       
  1044 				}		
       
  1045 			case RLbsNetworkRegistrationStatus::ENetworkRegistrationUnknown:
       
  1046 			default:
       
  1047 				{
       
  1048 				LBSLOG_WARN2(ELogP4, "Unrecognised TLbsNetworkRegistrationStatus (%d), defaulting to EExternalLocateOff",
       
  1049 							 netRegStatus);
       
  1050 				serviceStatus = CLbsAdmin::EExternalLocateOff;
       
  1051 				break;
       
  1052 				}
       
  1053 			}
       
  1054 		}
       
  1055 	else
       
  1056 		{
       
  1057 		LBSLOG_WARN2(ELogP4, "Failed to get TExternalLocateService, couldn't read roaming status (err %d), defaulting to EExternalLocateOff",  
       
  1058 					 err);		
       
  1059 		}
       
  1060 	
       
  1061 	aExternalLocateService = serviceStatus;
       
  1062 	}
       
  1063 
       
  1064 // ----------------------------------------------------------------------------- 
       
  1065 // CLbsPrivLocStateBase::CLbsPrivLocStateBase
       
  1066 // Description: Constructor
       
  1067 // ----------------------------------------------------------------------------- 
       
  1068 //
       
  1069 CLbsPrivLocStateBase::CLbsPrivLocStateBase(CLbsPrivLocFsm* aFsm)
       
  1070 :	iFsm(aFsm)
       
  1071 	{	
       
  1072 	}
       
  1073 // ----------------------------------------------------------------------------- 
       
  1074 // CLbsPrivLocStateBase::PrivacyHandler, MessageSwitch, LbsAdmin
       
  1075 // Description: Allows concrete states access to NRH resources passed to
       
  1076 // the FSM
       
  1077 // Returns: pointers.
       
  1078 // ----------------------------------------------------------------------------- 
       
  1079 //
       
  1080 CPrivacyHandler* CLbsPrivLocStateBase::PrivacyHandler()
       
  1081 	{
       
  1082 	return iFsm->PrivLocHandler().PrivacyHandler();
       
  1083 	}
       
  1084 CNGMessageSwitch* CLbsPrivLocStateBase::MessageSwitch()
       
  1085 	{
       
  1086 	return iFsm->PrivLocHandler().MessageSwitch();
       
  1087 	}
       
  1088 CLbsAdmin* CLbsPrivLocStateBase::LbsAdmin()
       
  1089 	{
       
  1090 	return iFsm->PrivLocHandler().LbsAdmin();
       
  1091 	}
       
  1092 CAgpsInterfaceHandler* CLbsPrivLocStateBase::AgpsInterface()
       
  1093 	{
       
  1094 	return iFsm->PrivLocHandler().AgpsHandler();
       
  1095 	}
       
  1096 
       
  1097 
       
  1098 TPositionModuleInfoExtended::TDeviceGpsModeCapabilities CLbsPrivLocStateBase::DeviceGpsModeCaps()
       
  1099 	{
       
  1100 	return iFsm->PrivLocHandler().DeviceGpsModeCaps();
       
  1101 	}
       
  1102 
       
  1103 CLbsAdmin::TLbsBehaviourMode CLbsPrivLocStateBase::BehaviourMode()
       
  1104 	{
       
  1105 	return iFsm->PrivLocHandler().BehaviourMode();
       
  1106 	}
       
  1107 
       
  1108 RLbsNetworkRegistrationStatus& CLbsPrivLocStateBase::LbsNetworkRegistrationStatus()
       
  1109 	{
       
  1110 	return iFsm->PrivLocHandler().NetworkRegistrationStatus();
       
  1111 	}
       
  1112 
       
  1113 /*
       
  1114  * increments the network initiated positioning status count
       
  1115  * and remembers that it has done
       
  1116  */
       
  1117 void CLbsPrivLocStateBase::IncrementPositioningStatus()
       
  1118     {
       
  1119     iFsm->PrivLocHandler().IncrementPositioningStatus();
       
  1120     iFsm->WasPositioningStatusIncremented() = ETrue;
       
  1121     }
       
  1122 
       
  1123 
       
  1124 // ----------------------------------------------------------------------------- 
       
  1125 // 
       
  1126 // ----------------------- Class CLbsPrivLocIdleState --------------------
       
  1127 //
       
  1128 // Implements the Idle state of the Privacy and Location Request Handler
       
  1129 //
       
  1130 // ----------------------------------------------------------------------------- 
       
  1131 //
       
  1132 
       
  1133 // ----------------------------------------------------------------------------- 
       
  1134 // CLbsPrivLocIdleState::NewL
       
  1135 // Description: CLbsPrivLocIdleState static constructor 
       
  1136 // ----------------------------------------------------------------------------- 
       
  1137 //
       
  1138 CLbsPrivLocIdleState* CLbsPrivLocIdleState::NewL(CLbsPrivLocFsm* aFsm)
       
  1139 	{
       
  1140 	return new (ELeave) CLbsPrivLocIdleState(aFsm);
       
  1141 	}
       
  1142 	
       
  1143 // ----------------------------------------------------------------------------- 
       
  1144 // CLbsPrivLocIdleState::CLbsPrivLocIdleState
       
  1145 // Description: CLbsPrivLocIdleState constructor.
       
  1146 // ----------------------------------------------------------------------------- 
       
  1147 //
       
  1148 CLbsPrivLocIdleState::CLbsPrivLocIdleState(CLbsPrivLocFsm* aFsm) 
       
  1149 : CLbsPrivLocStateBase(aFsm)
       
  1150 	{
       
  1151 	}
       
  1152 
       
  1153 // ----------------------------------------------------------------------------- 
       
  1154 // CLbsPrivLocIdleState::OnEntry
       
  1155 // Description: Carries out tasks required on entry to the state.
       
  1156 // ----------------------------------------------------------------------------- 
       
  1157 //
       
  1158 void CLbsPrivLocIdleState::OnEntry(const TPrivLocCommonParams& aStateParams)
       
  1159 	{
       
  1160 	CLbsPrivLocStateBase::OnEntry(aStateParams);
       
  1161 	}
       
  1162 
       
  1163 // ----------------------------------------------------------------------------- 
       
  1164 // CLbsPrivLocIdleState::OnExit
       
  1165 // Description: Carries out tasks required on exit from the state.
       
  1166 // Panics if the exit reason is not handled by the base state exit
       
  1167 // ----------------------------------------------------------------------------- 
       
  1168 //
       
  1169 TBool CLbsPrivLocIdleState::OnExit()
       
  1170 	{
       
  1171 	TBool consumed = CLbsPrivLocStateBase::OnExit();
       
  1172 	// If the exit reason wasn't handled, panic (should only happen in development)
       
  1173 	__ASSERT_DEBUG(consumed, Panic(ENrhPanicIdleUnknownExitReason));
       
  1174 	
       
  1175 	return(consumed);
       
  1176 	}
       
  1177 	
       
  1178 // ----------------------------------------------------------------------------- 
       
  1179 // CLbsPrivLocIdleState::OnNetLocRequest
       
  1180 // Description: The Message Switch has forwarded a request for a control 
       
  1181 // measurement.
       
  1182 // If the session type is anything but MTLR, then it is processed, otherwise
       
  1183 // a privacy request is generated
       
  1184 // ----------------------------------------------------------------------------- 
       
  1185 //
       
  1186 void CLbsPrivLocIdleState::OnNetLocRequest(
       
  1187 		const TLbsNetSessionIdInt& aSessionId,
       
  1188 		const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
  1189 		TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
  1190 		TBool aIsEmergency,
       
  1191         const TLbsNetPosRequestQualityInt& aQuality)
       
  1192     {
       
  1193     iFsm->SessionType() = aSessionType;
       
  1194     if(iFsm->WasPrivacyResponseReceivedStateExited())
       
  1195         {
       
  1196         // The request relates to a rejected privacy request
       
  1197         // or a request for this session which has already been answered. 
       
  1198         // In either case, it should be refused. The message is sent to the
       
  1199         // network gateway as a part of exit from the state, but we want to 
       
  1200         // remain in Idle state.
       
  1201         iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitCancelledByPrivacyController, KErrAccessDenied);
       
  1202         iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId);
       
  1203         }
       
  1204     else
       
  1205         {
       
  1206         TInt numMethods = aPosRequestMethod.NumPosMethods();
       
  1207         if (numMethods==1)
       
  1208             {
       
  1209             TLbsNetPosMethodInt netPosMethod;
       
  1210             aPosRequestMethod.GetPosMethod(0,netPosMethod);
       
  1211                     
       
  1212             if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted))
       
  1213                 {
       
  1214                 iFsm->TapMode() = ETrue;
       
  1215                 }
       
  1216             }
       
  1217         
       
  1218             
       
  1219         if ((aSessionType != MLbsNetworkProtocolObserver::EServiceMobileTerminated) &&
       
  1220             (aSessionType != MLbsNetworkProtocolObserver::EServiceNetworkInduced))
       
  1221             {
       
  1222             iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone);
       
  1223             TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId,
       
  1224                                                             aPosRequestMethod,
       
  1225                                                             aSessionType,
       
  1226                                                             aIsEmergency,
       
  1227                                                             aQuality);
       
  1228             iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams);
       
  1229             }
       
  1230             else
       
  1231             {
       
  1232             // It's a request for a different session. Need to find out what to do with it.
       
  1233             HandleLocRequest(aSessionId, aPosRequestMethod, 
       
  1234                                     aSessionType,aIsEmergency,
       
  1235                                     aQuality);
       
  1236             }
       
  1237         }
       
  1238     }
       
  1239 
       
  1240 // ----------------------------------------------------------------------------- 
       
  1241 // CLbsPrivLocIdleState::OnMTLRRequest
       
  1242 // Description: The Message Switch has forwarded a request for a location update
       
  1243 // (a privacy request) 
       
  1244 // ----------------------------------------------------------------------------- 
       
  1245 //
       
  1246 void CLbsPrivLocIdleState::OnMTLRRequest(const TLbsNetSessionIdInt& aSessionId,
       
  1247 				TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType,
       
  1248 				TBool aIsEmergency,
       
  1249 				const TLbsExternalRequestInfo& aExternalRequestInfo,
       
  1250 				const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy)
       
  1251 	{
       
  1252 	iFsm->SessionType() = aSessionType;
       
  1253 	iFsm->ExternalRequestType() = aExternalRequestInfo.RequestType();
       
  1254 	iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitPrivacyRequestReceived, KErrNone);
       
  1255 	TPrivLocWaitPrivResponseParams privacyRequestParams(	aSessionId, 
       
  1256 													aSessionType,
       
  1257 													aExternalRequestInfo, 
       
  1258 													aNetPosRequestPrivacy,
       
  1259 													aIsEmergency);
       
  1260 	iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitPrivacyResponse, privacyRequestParams);
       
  1261 	}
       
  1262 
       
  1263 /** Called when a reference position arrives from the network.
       
  1264  * 
       
  1265 */
       
  1266 void CLbsPrivLocIdleState::OnNetLocReferenceUpdate(
       
  1267 		const TLbsNetSessionIdInt& /*aSessionId*/, 
       
  1268 		const TPositionInfoBase& /* aPosInfo */)
       
  1269 	{
       
  1270 	// note that the reference postion is stored by the message switch
       
  1271 	// so here we don't need to save it again!
       
  1272 	}
       
  1273 	
       
  1274 // ----------------------------------------------------------------------------- 
       
  1275 // 
       
  1276 // ----------------------- Class CLbsPrivLocWaitPrivRespState --------------------
       
  1277 //
       
  1278 // Implements the Idle state of the Privacy and Location Request Handler
       
  1279 //
       
  1280 // ----------------------------------------------------------------------------- 
       
  1281 //
       
  1282 
       
  1283 // ----------------------------------------------------------------------------- 
       
  1284 // CLbsPrivLocWaitPrivRespState::NewL
       
  1285 // Description: CLbsPrivLocIdleState static constructor 
       
  1286 // ----------------------------------------------------------------------------- 
       
  1287 //
       
  1288 CLbsPrivLocWaitPrivRespState* CLbsPrivLocWaitPrivRespState::NewL(CLbsPrivLocFsm* aFsm)
       
  1289 	{
       
  1290 	return new (ELeave) CLbsPrivLocWaitPrivRespState(aFsm);
       
  1291 	}
       
  1292 	
       
  1293 // ----------------------------------------------------------------------------- 
       
  1294 // CLbsPrivLocWaitPrivRespState::CLbsPrivLocWaitPrivRespState
       
  1295 // Description: CLbsPrivLocWaitPrivRespState constructor.
       
  1296 // ----------------------------------------------------------------------------- 
       
  1297 //
       
  1298 CLbsPrivLocWaitPrivRespState::CLbsPrivLocWaitPrivRespState(CLbsPrivLocFsm* aFsm)
       
  1299 : CLbsPrivLocStateBase(aFsm)
       
  1300 	{
       
  1301 	}
       
  1302 
       
  1303 // ----------------------------------------------------------------------------- 
       
  1304 // CLbsPrivLocWaitPrivRespState::OnEntry
       
  1305 // Description: Actions performed when the state is entered.
       
  1306 // Unpack the parameters and issue the privacy request.
       
  1307 // ----------------------------------------------------------------------------- 
       
  1308 //
       
  1309 void CLbsPrivLocWaitPrivRespState::OnEntry(const TPrivLocCommonParams& aStateParams)
       
  1310 	{
       
  1311 	CLbsPrivLocStateBase::OnEntry(aStateParams);
       
  1312 	const TPrivLocWaitPrivResponseParams& params = TPrivLocWaitPrivResponseParams::Cast(const_cast<TPrivLocCommonParams&>(aStateParams));	
       
  1313 	iFsm->SessionType() = params.iSessionType;
       
  1314 	iFsm->IsEmergency() = params.iIsEmergency;
       
  1315 
       
  1316 	PrivacyHandler()->ProcessNetworkLocationRequest(iFsm->SessionId(), 
       
  1317 													iFsm->SessionType(),
       
  1318 													params.iExternalRequestInfo, 
       
  1319 													params.iNetPosRequestPrivacy,
       
  1320 													iFsm->IsEmergency());	
       
  1321 	}
       
  1322 
       
  1323 // ----------------------------------------------------------------------------- 
       
  1324 // CLbsPrivLocWaitPrivRespState::OnExit
       
  1325 // Description: Actions performed on leaving the state.
       
  1326 // ----------------------------------------------------------------------------- 
       
  1327 //
       
  1328 TBool CLbsPrivLocWaitPrivRespState::OnExit()
       
  1329 	{
       
  1330 	TInt consumed = EFalse;
       
  1331 	switch(iFsm->ExitData().iExitReason)
       
  1332 		{
       
  1333 		case TPrivLocStateExitData::EExitPrivacyResponseReceived:
       
  1334 			{
       
  1335             // Remember that we exited the privacy response received state 
       
  1336 			// so that we can deny the network location requests in the idle staet.
       
  1337 
       
  1338             iFsm->WasPrivacyResponseReceivedStateExited() = ETrue;
       
  1339 
       
  1340 			
       
  1341 			// For the NI case a Reference position may have arrived by now
       
  1342 			// So we must pass this onto the privacy handler.
       
  1343 
       
  1344 			if (iFsm->SessionType() == MLbsNetworkProtocolObserver::EServiceNetworkInduced) 
       
  1345 				{
       
  1346 				if (iFsm->PrivacyResponse() == CLbsNetworkProtocolBase::EPrivacyResponseAccepted)
       
  1347 					{
       
  1348 					TPositionInfo posInfo;
       
  1349 					TInt err = MessageSwitch()->GetNetworkReferencePosition(iFsm->SessionId(), posInfo);
       
  1350 					if (KErrNone == err)
       
  1351 						{
       
  1352 						if (!iFsm->RefPosProcessed())
       
  1353 							{
       
  1354 							iFsm->RefPosProcessed() = ETrue;
       
  1355 							PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), posInfo);
       
  1356 							}
       
  1357 				
       
  1358 						}
       
  1359 					
       
  1360 					}
       
  1361 				}		
       
  1362 				
       
  1363 			// For MtLrs the Protocol module should not
       
  1364 			// send a REF position until after we have sent the Priv response to the PM 
       
  1365 	            
       
  1366 			// Inform network of the privacy response for normal privacy requests.
       
  1367 			if (iFsm->SessionType() == TLbsNetworkEnumInt::EServiceMobileTerminated)
       
  1368 				{
       
  1369 				MessageSwitch()->SendMTLRResponse(iFsm->SessionId(), iFsm->PrivacyResponse(), iFsm->PrivacyResponseReason(), iFsm->IsEmergency());	
       
  1370 				}
       
  1371 
       
  1372 			// Inform network of a rejected privacy response via a "RespondLocationRequest" for faked privacy requests (generated internaly).
       
  1373 			else if ((iFsm->SessionType() == TLbsNetworkEnumInt::EServiceNetworkInduced) && (iFsm->PrivacyResponse() == TLbsNetworkEnumInt::EPrivacyResponseRejected))
       
  1374 				{
       
  1375 				// The faked privacy request was rejected, so reject the location request.
       
  1376 				TPositionInfo dummyPosInfo;
       
  1377 				TTime dummyTime;
       
  1378 				TLbsNetPosRequestQualityInt dummyQuality;
       
  1379 
       
  1380 				MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
  1381 													KErrAccessDenied,
       
  1382 													dummyQuality,
       
  1383 													dummyPosInfo,
       
  1384 													dummyTime,
       
  1385 													iFsm->IsEmergency());
       
  1386 				}
       
  1387 			
       
  1388 			consumed = ETrue;
       
  1389 			break;
       
  1390 			}
       
  1391 
       
  1392 		case TPrivLocStateExitData::EExitCancelledByPrivacyController:
       
  1393 			{
       
  1394 			// Send a cancel to the network gateway
       
  1395 			iFsm->PrivacyResponse() = TLbsNetworkEnumInt::EPrivacyResponseRejected;
       
  1396 			iFsm->PrivacyResponseReason() = KErrCancel;
       
  1397 			MessageSwitch()->SendMTLRResponse(iFsm->SessionId(), iFsm->PrivacyResponse(), iFsm->PrivacyResponseReason(), iFsm->IsEmergency());
       
  1398 			consumed = ETrue;
       
  1399 			}
       
  1400 			break;
       
  1401 
       
  1402 		default:
       
  1403 			{
       
  1404 			consumed = CLbsPrivLocStateBase::OnExit();
       
  1405 			// If the exit reason wasn't handled, panic (should only happen in development)
       
  1406 			__ASSERT_DEBUG(consumed, Panic(ENrhPanicWaitPrivRespUnknownExitReason));
       
  1407 			break;
       
  1408 			}
       
  1409 		}
       
  1410 		
       
  1411 	iFsm->LocReqReceived() = EFalse;
       
  1412 
       
  1413 	return(consumed);
       
  1414 	}
       
  1415 
       
  1416 // ----------------------------------------------------------------------------- 
       
  1417 // CLbsPrivLocWaitPrivRespState::OnRespondNetworkLocationRequest
       
  1418 // Description: Pass on a received privacy response to the network gateway, if
       
  1419 // it relates to the current session.
       
  1420 // ----------------------------------------------------------------------------- 
       
  1421 //
       
  1422 void CLbsPrivLocWaitPrivRespState::OnRespondNetworkLocationRequest(
       
  1423 											const TLbsNetSessionIdInt& aSessionId, 
       
  1424 											TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult,
       
  1425 											TInt /* aResponseReason*/)
       
  1426 	{
       
  1427 
       
  1428 	if(aSessionId == iFsm->SessionId())
       
  1429 		{
       
  1430 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitPrivacyResponseReceived, KErrNone);
       
  1431 		iFsm->PrivacyResponse() = aRequestResult;
       
  1432 		if(iFsm->PrivacyResponse() == TLbsNetworkEnumInt::EPrivacyResponseAccepted)
       
  1433 			{
       
  1434 			// Tell the AGPS handler that we are going to start a location request soon.
       
  1435 			AgpsInterface()->PreStartPositioning(iFsm->SessionId(), iFsm->IsEmergency());
       
  1436 			
       
  1437 			// Set the Positioning Status for the UI indicator.
       
  1438 			// Not done for silent requests.
       
  1439 			if (iFsm->ExternalRequestType() < TLbsExternalRequestInfo::ERequestSingleShotSilent)
       
  1440 			    {
       
  1441                 IncrementPositioningStatus();
       
  1442 			    }
       
  1443 			
       
  1444 			if(iFsm->LocReqReceived())
       
  1445 				{				
       
  1446 				TPrivLocWaitLocationUpdateParams updateRequestParams(iFsm->SessionId(),
       
  1447 																iFsm->PosRequestMethod(),
       
  1448 																iFsm->SessionType(),
       
  1449 																iFsm->IsEmergency(),
       
  1450 																iFsm->NetRequestQuality());
       
  1451 				iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams);	            
       
  1452 				}
       
  1453 			else
       
  1454 				{
       
  1455 				TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(),
       
  1456 																		iFsm->IsEmergency(),
       
  1457 																		EFalse);
       
  1458 				iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams);
       
  1459 				}
       
  1460 			}
       
  1461 		else
       
  1462 			{
       
  1463 			iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId);
       
  1464 			}
       
  1465 		}
       
  1466 	}
       
  1467 	
       
  1468 // ----------------------------------------------------------------------------- 
       
  1469 // CLbsPrivLocWaitPrivRespState::OnNetLocRequest
       
  1470 // Description: The Message Switch has forwarded a request for a control 
       
  1471 // measurement.
       
  1472 // If the session Id is the same as the current one, then save the parameters
       
  1473 // so that the request can be issued when privacy is accepted.
       
  1474 // Otherwise (the session Id is different) a cancel is implied and we cancel 
       
  1475 // the current session and start another, which may or may not require a new 
       
  1476 // privacy query.
       
  1477 // ----------------------------------------------------------------------------- 
       
  1478 //
       
  1479 void CLbsPrivLocWaitPrivRespState::OnNetLocRequest(
       
  1480 		const TLbsNetSessionIdInt& aSessionId,
       
  1481 		const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
  1482 		TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
  1483 		TBool aIsEmergency,
       
  1484         const TLbsNetPosRequestQualityInt& aQuality)
       
  1485 	{	
       
  1486 	TInt numMethods = aPosRequestMethod.NumPosMethods();
       
  1487 	if (numMethods==1)
       
  1488 		{
       
  1489 		TLbsNetPosMethodInt netPosMethod;
       
  1490 		aPosRequestMethod.GetPosMethod(0,netPosMethod);
       
  1491 				
       
  1492 		if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted))
       
  1493 			{
       
  1494 			iFsm->TapMode() = ETrue;
       
  1495 			}
       
  1496 		}
       
  1497 	if(aSessionId == iFsm->SessionId() && 
       
  1498 		aIsEmergency == iFsm->IsEmergency() &&
       
  1499 		aSessionType == iFsm->SessionType())
       
  1500 		{
       
  1501 		iFsm->PosRequestMethod() = aPosRequestMethod;
       
  1502 		iFsm->NetRequestQuality() = aQuality;
       
  1503 		iFsm->LocReqReceived() = ETrue;
       
  1504 		}
       
  1505 	else
       
  1506 		{
       
  1507 		// It's a request for different session. Need to find out what to do with it.
       
  1508 		HandleLocRequest(aSessionId,aPosRequestMethod, 
       
  1509 							aSessionType,aIsEmergency,
       
  1510 							aQuality);
       
  1511 		}
       
  1512 	}
       
  1513 	
       
  1514 	
       
  1515 void CLbsPrivLocWaitPrivRespState::OnMTLRRequest(const TLbsNetSessionIdInt& /*aSessionId*/,
       
  1516 					   TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/, 
       
  1517 					   TBool /*aIsEmergency*/,
       
  1518 					   const TLbsExternalRequestInfo& /*aExternalRequestInfo*/,
       
  1519 					   const TLbsNetPosRequestPrivacyInt& /*aNetPosRequestPrivacy*/)
       
  1520 	{
       
  1521 	// this can never happen. If the Fsm is in the WaitPrivRespState then 
       
  1522 	// any arrival of a MTLR request would start a new session (no implicit cancel!)
       
  1523 	// and the OnMTLRRequest()would be directed to that session not this one
       
  1524 	__ASSERT_DEBUG(EFalse, Panic(ENrhPanicBadParamType));
       
  1525 	}
       
  1526 
       
  1527 /** Called when a reference position arrives from the network.
       
  1528  *  
       
  1529 */
       
  1530 void CLbsPrivLocWaitPrivRespState::OnNetLocReferenceUpdate(
       
  1531 		const TLbsNetSessionIdInt& /*aSessionId*/, 
       
  1532 		const TPositionInfoBase& /*aPosInfo*/)
       
  1533 	{
       
  1534 	// note that the reference postion is stored by the message switch
       
  1535 	// so here we don't need to save it again!
       
  1536 	}
       
  1537 	
       
  1538 	
       
  1539 // ----------------------------------------------------------------------------- 
       
  1540 // 
       
  1541 // ----------------------- Class CLbsPrivLocWaitLocUpdateState --------------------
       
  1542 //
       
  1543 // Implements the Wait For Location Update state of the Privacy and Location 
       
  1544 // Request Handler
       
  1545 //
       
  1546 // On entry, issues a location update request then starts a timer and waits for 
       
  1547 // a response.
       
  1548 //
       
  1549 // ----------------------------------------------------------------------------- 
       
  1550 //
       
  1551 
       
  1552 // ----------------------------------------------------------------------------- 
       
  1553 // CLbsPrivLocWaitLocUpdateState::NewL
       
  1554 // Description: CLbsPrivLocWaitLocUpdateState static constructor 
       
  1555 // ----------------------------------------------------------------------------- 
       
  1556 //
       
  1557 CLbsPrivLocWaitLocUpdateState* CLbsPrivLocWaitLocUpdateState::NewL(CLbsPrivLocFsm* aFsm)
       
  1558 	{
       
  1559 	CLbsPrivLocWaitLocUpdateState* self; 
       
  1560 	self = new (ELeave) CLbsPrivLocWaitLocUpdateState(aFsm);
       
  1561 	CleanupStack::PushL(self);
       
  1562 	self->ConstructL();
       
  1563 	CleanupStack::Pop(self);
       
  1564 	return(self);	
       
  1565 	}
       
  1566 	
       
  1567 // ----------------------------------------------------------------------------- 
       
  1568 // CLbsPrivLocWaitLocUpdateState::CLbsPrivLocWaitLocUpdateState
       
  1569 // Description: CLbsPrivLocWaitLocUpdateState constructor.
       
  1570 // ----------------------------------------------------------------------------- 
       
  1571 //
       
  1572 CLbsPrivLocWaitLocUpdateState::CLbsPrivLocWaitLocUpdateState(CLbsPrivLocFsm* aFsm)
       
  1573 : CLbsPrivLocStateBase(aFsm)
       
  1574 	{
       
  1575 	}
       
  1576 
       
  1577 // ----------------------------------------------------------------------------- 
       
  1578 // CLbsPrivLocWaitLocUpdateState::~CLbsPrivLocWaitLocUpdateState
       
  1579 // Description: CLbsPrivLocWaitLocUpdateState destructor.
       
  1580 // ----------------------------------------------------------------------------- 
       
  1581 //
       
  1582 CLbsPrivLocWaitLocUpdateState::~CLbsPrivLocWaitLocUpdateState()
       
  1583 	{
       
  1584 	}
       
  1585 
       
  1586 // ----------------------------------------------------------------------------- 
       
  1587 // CLbsPrivLocIdleState::ConstructL
       
  1588 // Description: CLbsPrivLocIdleState second-phase constructor.
       
  1589 // ----------------------------------------------------------------------------- 
       
  1590 //
       
  1591 void CLbsPrivLocWaitLocUpdateState::ConstructL()
       
  1592 	{
       
  1593 	}
       
  1594 
       
  1595 
       
  1596 // ----------------------------------------------------------------------------- 
       
  1597 // CLbsPrivLocWaitLocUpdateState::OnEntry
       
  1598 // Description: Carries out tasks required on entry to the state.
       
  1599 // Issues the location update request and starts a timer.
       
  1600 // ----------------------------------------------------------------------------- 
       
  1601 //
       
  1602 void CLbsPrivLocWaitLocUpdateState::OnEntry(const TPrivLocCommonParams& aStateParams)
       
  1603 	{
       
  1604 	TInt err(KErrNone);
       
  1605 	
       
  1606 	CLbsPrivLocStateBase::OnEntry(aStateParams);
       
  1607 	const TPrivLocWaitLocationUpdateParams& params = TPrivLocWaitLocationUpdateParams::Cast(aStateParams);	
       
  1608 	iFsm->IsEmergency() = params.iIsEmergency;
       
  1609 	iFsm->SessionType() = params.iSessionType;
       
  1610 	iFsm->PosRequestMethod() = params.iPosRequestMethod;
       
  1611 
       
  1612 	// If the network has not specified a positioning method, get the default
       
  1613 	// one from the admin settings.
       
  1614 	TLbsNetPosMethodInt netReqMethod;
       
  1615 	iFsm->PosRequestMethod().GetPosMethod(0, netReqMethod);		
       
  1616 	if (iFsm->PosRequestMethod().NumPosMethods() == 1
       
  1617 		&& (netReqMethod.PosMode() == TPositionModuleInfo::ETechnologyUnknown))
       
  1618 		{
       
  1619 		AgpsInterface()->GetDefaultPosMethod(iFsm->PosRequestMethod());
       
  1620 		}
       
  1621 
       
  1622     // We may use two sources for the required quality for the
       
  1623     // new location request, either:
       
  1624     // 1) The quality from the network (aQuality)
       
  1625     // 2) The quality defined in a quality profile (which profile to
       
  1626     //    use depends on the service type, e.g. MT-LR or X3P)
       
  1627     //
       
  1628     // We decide which to use based on the required quality from the network.
       
  1629     // Any invalid/unsupplied parameter is read from the quality profile 
       
  1630     // for the ocation request type.
       
  1631    	TBool maxFixTimeRequired = params.iQuality.MaxFixTime() == 0;
       
  1632     TBool minVerticalAccuracyRequired = 
       
  1633     				Math::IsNaN(params.iQuality.MinVerticalAccuracy());
       
  1634     TBool minHorizontalAccuracyRequired = 
       
  1635     				Math::IsNaN(params.iQuality.MinHorizontalAccuracy());
       
  1636     
       
  1637     if (maxFixTimeRequired || minVerticalAccuracyRequired || minHorizontalAccuracyRequired)
       
  1638     	{
       
  1639     	// Select which LbsAdmin setting to use for the
       
  1640     	// quality profile Id based on the type of location
       
  1641     	// request.
       
  1642 	    TLbsAdminSetting adminSetting(KLbsSettingNone);
       
  1643 	    switch (iFsm->SessionType())
       
  1644 	    	{
       
  1645 	    	case TLbsNetworkEnumInt::EServiceMobileTerminated:
       
  1646 	    	case TLbsNetworkEnumInt::EServiceNetworkInduced:
       
  1647 	    		{
       
  1648 	    		adminSetting = KLbsSettingQualityProfileExternalLocate;
       
  1649 	    		break;
       
  1650 	    		}
       
  1651 	    	case TLbsNetworkEnumInt::EServiceTransmitThirdParty:
       
  1652 	    		{
       
  1653 	    		adminSetting = KLbsSettingQualityProfileTransmitLocate;
       
  1654 	    		break;
       
  1655 	    		}
       
  1656 	    	case TLbsNetworkEnumInt::EServiceTriggeredMolr:
       
  1657                 // SUPL 2.0 "Triggered MOLR" request uses Self Locate Quality Profile
       
  1658 	    	case TLbsNetworkEnumInt::EServiceNetworkLocation:
       
  1659 	    		// This type of request should only get here in the case of a TA MOLR. Treat as Self-Locate
       
  1660 	    	case TLbsNetworkEnumInt::EServiceSelfLocation:
       
  1661 	    		{
       
  1662 	    		adminSetting = KLbsSettingQualityProfileSelfLocate;
       
  1663 	    		break;
       
  1664 	    		}
       
  1665 	    	default:
       
  1666 	    		{
       
  1667 				// We must not fail if it is an emergency request
       
  1668 				if (!iFsm->IsEmergency())
       
  1669 					{
       
  1670 					LBSLOG2(ELogP3, 
       
  1671 					"Unable to select quality profile for TLbsNetProtocolService (%d), using quality data from network instead.",
       
  1672 		    				iFsm->SessionType());
       
  1673 					__ASSERT_DEBUG(EFalse, Panic(ENrhPanicNoQualityProfile));
       
  1674 					}
       
  1675 	    		else
       
  1676 	    			{
       
  1677 	   				adminSetting = KLbsSettingQualityProfileExternalLocate;
       
  1678 	   				}
       
  1679 	    		}
       
  1680 	    	}
       
  1681 
       
  1682 		// Retrieve the Id of the quality profile to use
       
  1683 	    TLbsQualityProfileId profileId(KLbsNullQualityProfileId);
       
  1684 	    if (adminSetting != KLbsSettingNone)
       
  1685 	    	{
       
  1686 	    	LbsAdmin()->Get(adminSetting, profileId);
       
  1687 	    	}
       
  1688 
       
  1689 	    // Retrieve the data for the quality profile
       
  1690     	TQualityProfile qualityProfile;
       
  1691     	err = LbsQualityProfile::GetQualityProfileById(profileId, qualityProfile);
       
  1692     	if (err == KErrNone)
       
  1693     		{
       
  1694     		// Use the quality data from the quality profile for any missing/invalid data
       
  1695 			if(maxFixTimeRequired)
       
  1696 				{
       
  1697 				iFsm->GpsRequestQuality().SetMaxFixTime(qualityProfile.MaxFixTime());
       
  1698 				}
       
  1699 			else
       
  1700 				{
       
  1701 				iFsm->GpsRequestQuality().SetMaxFixTime(params.iQuality.MaxFixTime());
       
  1702 				}
       
  1703 			if(minHorizontalAccuracyRequired)
       
  1704 				{
       
  1705 				iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(qualityProfile.MinHorizontalAccuracy());
       
  1706 				}
       
  1707 			else
       
  1708 				{
       
  1709 				iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(params.iQuality.MinHorizontalAccuracy());
       
  1710 				}
       
  1711 			if(minVerticalAccuracyRequired)
       
  1712 				{
       
  1713 				iFsm->GpsRequestQuality().SetMinVerticalAccuracy(qualityProfile.MinVerticalAccuracy());
       
  1714 				}
       
  1715 			else
       
  1716 				{
       
  1717 				iFsm->GpsRequestQuality().SetMinVerticalAccuracy(params.iQuality.MinVerticalAccuracy());				
       
  1718 				}
       
  1719     		}
       
  1720 		else
       
  1721 			{
       
  1722 			// We should not fail if we are emergency
       
  1723 			if (!iFsm->IsEmergency())
       
  1724 				{
       
  1725 				// We couldn't find the quality profile with the given Id.
       
  1726 				// This is an error, so reject the location request.
       
  1727 				TPositionInfo dummyPosInfo;
       
  1728 				TTime dummyTime;
       
  1729 				TLbsNetPosRequestQualityInt dummyQuality;
       
  1730 				MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
  1731 									KErrAccessDenied,
       
  1732 										dummyQuality,
       
  1733 										dummyPosInfo,
       
  1734 										dummyTime,
       
  1735 										iFsm->IsEmergency());
       
  1736 			
       
  1737 				// if this location request is the result of a privacy request,
       
  1738 				// then notify the privacy handler of the error
       
  1739 				if ((params.iSessionType == TLbsNetworkEnumInt::EServiceMobileTerminated) ||
       
  1740 					(params.iSessionType == TLbsNetworkEnumInt::EServiceNetworkInduced))
       
  1741 					{
       
  1742 					iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, KErrAccessDenied);
       
  1743 					}
       
  1744 				else
       
  1745 					{
       
  1746 					iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitBadQualityProfile, KErrNone);
       
  1747 					}
       
  1748 
       
  1749 				// Whatever the result, this session is finished, so return to idle.
       
  1750 				iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, iFsm->SessionId());
       
  1751 				return;
       
  1752 				} // if (!iIsEmergency)
       
  1753 			else
       
  1754 				{
       
  1755 				// Just set some defaults
       
  1756 				TTimeIntervalMicroSeconds timeout(30000000);
       
  1757 				iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(50);
       
  1758 				iFsm->GpsRequestQuality().SetMinVerticalAccuracy(1000);
       
  1759 				iFsm->GpsRequestQuality().SetMaxFixTime(timeout);
       
  1760 				}
       
  1761     		}
       
  1762     	}
       
  1763     else
       
  1764     	{
       
  1765     	// Use the quality parameters supplied with the request.
       
  1766     	iFsm->GpsRequestQuality().SetMinHorizontalAccuracy(params.iQuality.MinHorizontalAccuracy());
       
  1767     	iFsm->GpsRequestQuality().SetMinVerticalAccuracy(params.iQuality.MinVerticalAccuracy());
       
  1768     	iFsm->GpsRequestQuality().SetMaxFixTime(params.iQuality.MaxFixTime());
       
  1769     	}
       
  1770 
       
  1771 
       
  1772     // Check for any existing position updates in case they meet the
       
  1773     // MaxFixAge and quality requirements for this request.
       
  1774     TInt updateReason;
       
  1775     err = AgpsInterface()->GetPosition(updateReason, 
       
  1776     								   iFsm->GpsPosition(), 
       
  1777     								   iFsm->ActualTime());
       
  1778     if (err == KErrNone)
       
  1779     	{
       
  1780 		TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(),
       
  1781 																iFsm->IsEmergency(),
       
  1782 																EFalse,
       
  1783 																updateReason);
       
  1784 
       
  1785     	// Check the existing update in case it meets the MaxFixAge and quality requirements for this request.
       
  1786     	if (params.iQuality.MaxFixAge() > 0)
       
  1787     		{
       
  1788     		TTime now;
       
  1789     		now.UniversalTime();
       
  1790     		TTimeIntervalMicroSeconds age(Max((now.Int64() - iFsm->ActualTime().Int64()), TInt64(0)));
       
  1791     		if (updateReason == KErrNone
       
  1792     			&& (age <= params.iQuality.MaxFixAge())
       
  1793     			&& ReceivedFixIsAccurate())
       
  1794     			{
       
  1795     			// Accurate update that is within the MaxFixAge time limit,
       
  1796     			// so return it straight away.
       
  1797     			iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, updateReason);
       
  1798     			iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams);
       
  1799     			return;
       
  1800     			}
       
  1801     		}
       
  1802     		
       
  1803 
       
  1804 		// Special feature behaviour!
       
  1805 		// If the admin setting KLbsSpecialFeatureIntermediateFutileUpdate is on,
       
  1806 		// it means that we should check to see if a futile update has happened
       
  1807 		// since the first location request of this session. This might happen
       
  1808 		// in a hybrid session, if the GPS module sends a futile update when there
       
  1809 		// is no outstanding location request in the NRH. E.g. in the gap between
       
  1810 		// sending the response for one hybrid loc request and getting the next
       
  1811 		// loc request from the network.
       
  1812 		//
       
  1813 		// Note: This only really applies to hybrid of TA position modes, because
       
  1814 		//       in TB or autonomous you only have one location request per 
       
  1815 		//       session.
       
  1816     	else if (iFsm->IsSpecialFeatureIntermediateFutileUpdateOn())
       
  1817     		{
       
  1818 		    // If this is the first request for a new sessionId, record the current session id.
       
  1819 		    // We need to know this for terminal assisted or hybrid requests, in case
       
  1820 		    // we need to check for a futile update that has happened in the gap between
       
  1821 		    // one location response and the next location update request.
       
  1822 		    if (iFsm->LastLocReqSessionId() != iFsm->SessionId())
       
  1823 		    	{
       
  1824 		    	iFsm->LastLocReqSessionId() = iFsm->SessionId();
       
  1825 		    	}
       
  1826 		    else
       
  1827 				{
       
  1828 				// Before sending the location request, see if a futile update has 
       
  1829 				// happened since the start of the session (in general only terminal-assisted 
       
  1830 				// and hybrid requests should have more than one location request
       
  1831 			    // per session, however the SUPL PM will have more than one for all request modes).
       
  1832    			    TGpsRequestMode gpsMode = AgpsInterface()->ConvertPosMethodToGpsRequestMode(iFsm->PosRequestMethod());
       
  1833 				if ((updateReason == KPositionCalculationFutile) && 
       
  1834 					((gpsMode == EGpsRequestModeTerminalAssisted) || (gpsMode == EGpsRequestModeHybrid)))
       
  1835 					{
       
  1836 					// Return last measurement straight away.
       
  1837 					iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, updateReason);
       
  1838 					iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams);
       
  1839 		    		return;
       
  1840 					}
       
  1841 				}
       
  1842     		}
       
  1843     	}
       
  1844 
       
  1845     
       
  1846 	// Issue the request and supply pointers to the data to be updated
       
  1847     iFsm->LocationFixReceived() = EFalse;
       
  1848     iFsm->MeasurementInfoReceived() = EFalse;
       
  1849     err = AgpsInterface()->StartPositioning(iFsm->SessionId(),
       
  1850 								    		iFsm->PosRequestMethod(),
       
  1851 											iFsm->GpsRequestQuality(),
       
  1852 											iFsm->IsEmergency());
       
  1853 	if (KErrNone == err)
       
  1854 		{
       
  1855 		iFsm->LocationUpdateTimer().EventAfter(iFsm->GpsRequestQuality().MaxFixTime(), 1);
       
  1856     	iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitReasonNone, KErrNone);
       
  1857 		}
       
  1858 	else
       
  1859 		{
       
  1860 		// Error sending the location request, send a location response
       
  1861 		// with the error and go to Idle state.
       
  1862     	iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitBadLocationRequest, err);
       
  1863     	iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, iFsm->SessionId());
       
  1864 		}
       
  1865 	}
       
  1866 
       
  1867 // ----------------------------------------------------------------------------- 
       
  1868 // CLbsPrivLocWaitLocUpdateState::OnExit
       
  1869 // Description: Carries out tasks required on exit from the state.
       
  1870 // Cancels the location update request and stops the timer.
       
  1871 // ----------------------------------------------------------------------------- 
       
  1872 //
       
  1873 TBool CLbsPrivLocWaitLocUpdateState::OnExit()
       
  1874 	{	
       
  1875 	// Cancel the update timer.
       
  1876 	iFsm->LocationUpdateTimer().Cancel();
       
  1877 	
       
  1878 	TInt consumed = EFalse;
       
  1879 	switch(iFsm->ExitData().iExitReason)
       
  1880 		{
       
  1881 		case TPrivLocStateExitData::EExitLocFixReceived:
       
  1882 			{
       
  1883 			// Don't cancel the location request yet, but tell the AGPS interface
       
  1884 			// handler to put it on 'hold'. If we are in a hybrid or terminal-assisted
       
  1885 			// request then we are going to get another location request very shortly
       
  1886 			// anyway...
       
  1887 			AgpsInterface()->HoldPositioning(iFsm->SessionId(), KErrNone);
       
  1888 	
       
  1889 			// Report the position to the message switch
       
  1890 			MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
  1891 												iFsm->ExitData().iExitInfo,
       
  1892             	                             	iFsm->GpsRequestQuality(),
       
  1893             	                             	iFsm->GpsPosition(),
       
  1894             	                             	iFsm->ActualTime(),
       
  1895             	                             	iFsm->IsEmergency());
       
  1896 
       
  1897 			// For MTLR pass the data to the privacy handler 
       
  1898 			// in case the Privacy Controller wants it.
       
  1899 			if ((iFsm->ExitData().iExitInfo >= KErrNone) &&
       
  1900 				(iFsm->ExitData().iExitInfo != KPositionCalculationFutile) && 
       
  1901 				((iFsm->SessionType() == TLbsNetworkEnumInt::EServiceMobileTerminated) ||
       
  1902 				(iFsm->SessionType() == TLbsNetworkEnumInt::EServiceNetworkInduced)))
       
  1903 				{
       
  1904 				PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), 
       
  1905 						iFsm->GpsPosition());
       
  1906 				}
       
  1907 
       
  1908 			consumed = ETrue;
       
  1909 			break;
       
  1910 			}
       
  1911 
       
  1912 		case TPrivLocStateExitData::EExitLocMeasurementResultsReceived:
       
  1913 			{
       
  1914 			// Don't cancel the location request yet, but tell the AGPS interface
       
  1915 			// handler to put it on 'hold'. If we are in a hybrid or terminal-assisted
       
  1916 			// request then we are going to get another location request very shortly
       
  1917 			// anyway...
       
  1918 			AgpsInterface()->HoldPositioning(iFsm->SessionId(), KErrNone);
       
  1919 
       
  1920 			// Report the measurement data to the message switch, even if we
       
  1921 			// didn't get any. The error code will indicate that the data
       
  1922 			// is rubbish in that case.
       
  1923 			LBSLOG2(ELogP3, "CLbsPrivLocWaitLocUpdateState:returning with reason %d", iFsm->MeasurementInfoError());
       
  1924 
       
  1925 			MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
  1926 												iFsm->ExitData().iExitInfo,
       
  1927 												iFsm->GpsRequestQuality(),
       
  1928             	                             	iFsm->GpsMeasurementInfo(),
       
  1929             	                             	iFsm->ActualTime(),
       
  1930             	                             	iFsm->IsEmergency());
       
  1931 			break;	
       
  1932 			}
       
  1933 		
       
  1934 		case TPrivLocStateExitData::EExitTimedOut:
       
  1935 			{
       
  1936 			// Don't cancel the location request yet, but tell the AGPS interface
       
  1937 			// handler to put it on 'hold'. If we are in a hybrid or terminal-assisted
       
  1938 			// request then we are going to get another location request very shortly
       
  1939 			// anyway...
       
  1940 			AgpsInterface()->HoldPositioning(iFsm->SessionId(), KErrNone);
       
  1941 
       
  1942 			// If the request has timed out, then return whatever position 
       
  1943 			// data we have, but make it clear it's not what was requested.
       
  1944 			// If there's an error (probably KErrTimedOut) there's
       
  1945 			// nothing to report, so send dummy data with the error.			
       
  1946 			MessageSwitch()->SendNetLocResponse(iFsm->SessionId(), 
       
  1947 												iFsm->ExitData().iExitInfo,
       
  1948 												iFsm->GpsRequestQuality(),
       
  1949 												iFsm->GpsPosition(),
       
  1950 												iFsm->ActualTime(),
       
  1951 												iFsm->IsEmergency());
       
  1952 
       
  1953 			// For MTLR, pass the data to the privacy handler in case the Privacy
       
  1954 			// Controller wants it.
       
  1955 			// NB Don't send the update if the error is KErrTimedOut, as that means there's
       
  1956 			// nothing to report.
       
  1957 			if((iFsm->SessionType() == TLbsNetworkEnumInt::EServiceMobileTerminated) &&
       
  1958 			    (iFsm->ExitData().iExitInfo == KPositionQualityLoss))
       
  1959 				{
       
  1960 				PrivacyHandler()->ProcessNetworkPositionUpdate(iFsm->SessionId(), 
       
  1961 						iFsm->GpsPosition());
       
  1962 				}
       
  1963 
       
  1964 			consumed = ETrue;
       
  1965 			break;
       
  1966 			}
       
  1967 			
       
  1968 		case TPrivLocStateExitData::EExitCancelledByPrivacyController:
       
  1969 			{
       
  1970 			// Stop the location request immediately.
       
  1971 			AgpsInterface()->StopPositioning(iFsm->SessionId());
       
  1972 			
       
  1973 			// Send a SendExternalLocateCancel to NetGateWay- if the protcol module does not support this then
       
  1974 			// the Gateway will do nothing
       
  1975 			MessageSwitch()->SendExternalLocateCancel(iFsm->SessionId(), KErrCancel);
       
  1976 				
       
  1977 			// Send a location response with 'cancel' set to the network
       
  1978 			TPositionInfo dummyPosInfo;
       
  1979 			TTime dummyTime;
       
  1980 			TLbsNetPosRequestQualityInt dummyQuality;
       
  1981 			MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
  1982 												iFsm->ExitData().iExitInfo,
       
  1983 												dummyQuality,
       
  1984 												dummyPosInfo,
       
  1985 												dummyTime,
       
  1986 												iFsm->IsEmergency());
       
  1987 			
       
  1988 			consumed = ETrue;
       
  1989 			}
       
  1990 			break;
       
  1991 
       
  1992 		case TPrivLocStateExitData::EExitBadQualityProfile:
       
  1993 			{
       
  1994 			// Do nothing; we're just going back to Idle state
       
  1995 			consumed = ETrue;
       
  1996 			break;
       
  1997 			}
       
  1998 		
       
  1999 		case TPrivLocStateExitData::EExitBadLocationRequest:
       
  2000 			{
       
  2001 			// Error processing the location request - 
       
  2002 			// send a dummy response with an error code.
       
  2003 			TPositionInfo dummyPosInfo;
       
  2004 			TTime dummyTime;
       
  2005 			TLbsNetPosRequestQualityInt dummyQuality;
       
  2006 			MessageSwitch()->SendNetLocResponse(iFsm->SessionId(),
       
  2007 												iFsm->ExitData().iExitInfo,
       
  2008 												dummyQuality,
       
  2009 												dummyPosInfo,
       
  2010 												dummyTime,
       
  2011 												iFsm->IsEmergency());
       
  2012 			
       
  2013 			consumed = ETrue;
       
  2014 			break;
       
  2015 			}
       
  2016 		
       
  2017 		default:
       
  2018 			{
       
  2019 			consumed = CLbsPrivLocStateBase::OnExit();
       
  2020 			// If the exit reason wasn't handled, panic (should only happen in development)
       
  2021 			__ASSERT_DEBUG(consumed, Panic(ENrhPanicWaitLocUpdateUnknownExitReason));
       
  2022 			}
       
  2023 		}
       
  2024 	return(consumed);
       
  2025 	}
       
  2026 
       
  2027 // ----------------------------------------------------------------------------- 
       
  2028 // CLbsPrivLocIdleState::OnNetLocRequest
       
  2029 // Description: The Message Switch has forwarded a request for a network 
       
  2030 // location.
       
  2031 // ----------------------------------------------------------------------------- 
       
  2032 //
       
  2033 void CLbsPrivLocWaitLocUpdateState::OnNetLocRequest(const TLbsNetSessionIdInt& aSessionId, 
       
  2034 						const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
  2035 						 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
  2036 						 TBool aIsEmergency,
       
  2037 						 const TLbsNetPosRequestQualityInt& aQuality)
       
  2038 	{
       
  2039 	TInt numMethods = aPosRequestMethod.NumPosMethods();
       
  2040 	if (numMethods==1)
       
  2041 		{
       
  2042 		TLbsNetPosMethodInt netPosMethod;
       
  2043 		aPosRequestMethod.GetPosMethod(0,netPosMethod);
       
  2044 				
       
  2045 		if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted))
       
  2046 			{
       
  2047 			iFsm->TapMode() = ETrue;
       
  2048 			}
       
  2049 		}
       
  2050 	if(aSessionId != iFsm->SessionId())
       
  2051 		{
       
  2052 		/* This request is for a different session. Cancel the current one 
       
  2053 		 * and start a new one.
       
  2054 		 */
       
  2055 		HandleLocRequest(aSessionId,aPosRequestMethod,
       
  2056 							aSessionType,aIsEmergency,
       
  2057 							aQuality);
       
  2058 		}
       
  2059 	else
       
  2060 		{
       
  2061 		LBSLOG(ELogP3, "CLbsPrivLocWaitLocUpdateState::OnNetLocRequest: Matching SessionId.");
       
  2062 		TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId,
       
  2063 				aPosRequestMethod,
       
  2064 				aSessionType,
       
  2065 				aIsEmergency,
       
  2066 				aQuality);
       
  2067 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone);
       
  2068 		iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams);
       
  2069 		}
       
  2070 	}
       
  2071 
       
  2072 
       
  2073 void CLbsPrivLocWaitLocUpdateState::OnMTLRRequest(const TLbsNetSessionIdInt& /*aSessionId*/,
       
  2074 					   TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/, 
       
  2075 					   TBool /*aIsEmergency*/,
       
  2076 					   const TLbsExternalRequestInfo& /*aExternalRequestInfo*/,
       
  2077 					   const TLbsNetPosRequestPrivacyInt& /*aNetPosRequestPrivacy*/)
       
  2078 	{
       
  2079 	// this can never happen. If the Fsm is in the WaitLocUpdateState then 
       
  2080 	// any arrival of a MTLR request would start a new session and not
       
  2081 	// implicitly cancel the ongoing MTLR and the OnMTLRRequest()
       
  2082 	// would be directed to that session not this one
       
  2083 		
       
  2084 	}
       
  2085 	
       
  2086 // ----------------------------------------------------------------------------- 
       
  2087 // CLbsPrivLocWaitLocUpdateState::OnTimerEventL
       
  2088 // Description: The Location Update timer has expired.
       
  2089 // Cancel the request, and pass on the response if any has been received,
       
  2090 // otherwise report failure.
       
  2091 // ----------------------------------------------------------------------------- 
       
  2092 //
       
  2093 void CLbsPrivLocWaitLocUpdateState::OnTimerEventL(TInt /*aTimerId*/)
       
  2094 	{	
       
  2095 	LBSLOG(ELogP3, "CLbsPrivLocWaitLocUpdateState::OnTimerEventL");
       
  2096 	
       
  2097 	if(iFsm->MeasurementInfoReceived())
       
  2098 		{
       
  2099 		// A position fix may have been received, but it can't be accurate enough
       
  2100 		// (otherwise the request would have been completed before timeout), so 
       
  2101 		// return the most recent measurement info		
       
  2102 		LBSLOG(ELogP3, "OnTimerEventL, measurement data received");
       
  2103 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, 
       
  2104 									 iFsm->MeasurementInfoError());
       
  2105 		}
       
  2106 	else if(iFsm->LocationFixReceived())
       
  2107 		{
       
  2108 		// position received, but not accurate enough (or request would already have been completed)
       
  2109 		LBSLOG(ELogP3, "OnTimerEventL, inaccurate location data received");
       
  2110 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitTimedOut, 
       
  2111 									 KPositionQualityLoss);
       
  2112 		}
       
  2113 	else
       
  2114 		{
       
  2115 		// we've received no update (position / measurements)
       
  2116 		LBSLOG(ELogP3, "OnTimerEventL, NO measurement data received");
       
  2117 		LBSLOG(ELogP3, "(Setting exit info KErrPositionNoGpsUpdate");
       
  2118 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitTimedOut, 
       
  2119 									 KErrPositionNoGpsUpdate);
       
  2120 		}
       
  2121 
       
  2122 	SetExitState();	
       
  2123 	}
       
  2124 
       
  2125 // ----------------------------------------------------------------------------- 
       
  2126 // CLbsPrivLocWaitLocUpdateState::SetExitState
       
  2127 // Description: Works out the next state on the basis of the current session 
       
  2128 // type and whether any update has been received.
       
  2129 // ----------------------------------------------------------------------------- 
       
  2130 //
       
  2131 void CLbsPrivLocWaitLocUpdateState::SetExitState()
       
  2132 	{
       
  2133 	TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(),
       
  2134 															iFsm->IsEmergency(),
       
  2135 															EFalse,
       
  2136 															iFsm->ExitData().iExitInfo);
       
  2137 	iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, 
       
  2138 					locationRequestParams);
       
  2139 	}
       
  2140 
       
  2141 TBool CLbsPrivLocWaitLocUpdateState::ReceivedFixIsAccurate()
       
  2142 	{    
       
  2143 	TBool fixIsAccurate = EFalse;
       
  2144 
       
  2145 	// Compare the accuracy to the request values.
       
  2146 	// Make sure the location update is (A)GPS and not Network based.
       
  2147 	TPosition latestPosition;
       
  2148 	iFsm->GpsPosition().GetPosition(latestPosition);
       
  2149 	
       
  2150 	if ((latestPosition.HorizontalAccuracy() <= iFsm->GpsRequestQuality().MinHorizontalAccuracy()) &&
       
  2151 		(latestPosition.VerticalAccuracy() <= iFsm->GpsRequestQuality().MinVerticalAccuracy()) &&
       
  2152 		(iFsm->GpsPosition().PositionMode() != TPositionModuleInfo::ETechnologyNetwork))//Pure Reference Location
       
  2153 		{
       
  2154 		fixIsAccurate = ETrue;
       
  2155 		}
       
  2156 
       
  2157 	return(fixIsAccurate);
       
  2158     }
       
  2159 
       
  2160 /** Callback when a GPS position update arrives from AGPS manager.
       
  2161 */
       
  2162 void CLbsPrivLocWaitLocUpdateState::OnAgpsPositionUpdate(
       
  2163 	TInt aReason,
       
  2164 	const TPositionExtendedSatelliteInfo& aPosInfo,
       
  2165 	const TTime& aTimeStamp)
       
  2166 	{
       
  2167 	iFsm->GpsPosition() = aPosInfo;
       
  2168 	iFsm->ActualTime() = aTimeStamp;
       
  2169 	iFsm->LocationFixReceived() = ETrue;
       
  2170 	iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, aReason);
       
  2171 
       
  2172 	if (KErrNone == aReason)
       
  2173 		{
       
  2174 		if (iFsm->TapMode())
       
  2175 			{
       
  2176 			LBSLOG(ELogP1,"TAP mode) - NOT sending position to network");	
       
  2177 			return; // do NOT return AGPS postions to TAP mode sessions
       
  2178 			}
       
  2179 		// See if the reported accuracy matches the specified quality.
       
  2180 		// If the accuracy is good enough, report the position
       
  2181 		
       
  2182 		// if this session is TAP then discard the position
       
  2183 		
       
  2184 		if(ReceivedFixIsAccurate())
       
  2185 			{
       
  2186 			SetExitState();
       
  2187 			}
       
  2188 		}
       
  2189 	else if ((aReason <= KErrNone) || (KPositionCalculationFutile == aReason))
       
  2190 		{
       
  2191 		// GPS Manager can't provide a location update. return what we do have.
       
  2192 		if(iFsm->MeasurementInfoReceived())
       
  2193 			{
       
  2194 			LBSLOG(ELogP1,"CLbsPrivLocWaitLocUpdateState::OnPositionUpdate() - measurement received");	
       
  2195 			iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, aReason);
       
  2196 			}
       
  2197 		else
       
  2198 			{
       
  2199 			iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, aReason);				
       
  2200 			}
       
  2201 		SetExitState();
       
  2202 		}
       
  2203 	else if (KPositionEarlyComplete == aReason)
       
  2204 		{
       
  2205 		// Not an error. Report back what was accepted.
       
  2206 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocFixReceived, KErrNone);				
       
  2207 		SetExitState();	
       
  2208 		}
       
  2209 	else
       
  2210 		{
       
  2211 		// A real error
       
  2212 		SetExitState();
       
  2213 		}
       
  2214 	}
       
  2215 
       
  2216 /** Callback when a GPS measurement results update arrives from AGPS manager.
       
  2217 
       
  2218 Only location requests that are 'hybrid' or 'terminal assisted' should record 
       
  2219 the measurement results. Other types of request (autonomous, terminal based)
       
  2220 are only interested in the GPS position update.
       
  2221 */
       
  2222 void CLbsPrivLocWaitLocUpdateState::OnAgpsMeasurementUpdate(
       
  2223 	TInt aReason,
       
  2224 	const TPositionGpsMeasurementInfo& aPosInfo,
       
  2225 	const TTime& /*aTimeStamp*/)
       
  2226 	{
       
  2227 	// Check that we should be listening for measurement updates.
       
  2228 	
       
  2229 	TBool positionCalculationPossible = aPosInfo.PositionCalculationPossible();
       
  2230 	
       
  2231 	const TInt methodCount = iFsm->PosRequestMethod().NumPosMethods();
       
  2232 	for(TInt i = 0; i < methodCount; ++i)
       
  2233 		{
       
  2234 		TLbsNetPosMethodInt posMethod;
       
  2235 		iFsm->PosRequestMethod().GetPosMethod(i, posMethod);
       
  2236 		if((posMethod.PosMode() & KTerminalAssistedMode) == KTerminalAssistedMode)
       
  2237 			{
       
  2238 			iFsm->MeasurementInfoReceived() = ETrue;
       
  2239 			iFsm->MeasurementInfoError() = aReason;
       
  2240 			iFsm->GpsMeasurementInfo() = aPosInfo;
       
  2241 
       
  2242 			// don't wait until alpha2 time expires, instead
       
  2243 			// return measuremnts now
       
  2244 			if (positionCalculationPossible)
       
  2245 				{
       
  2246 				iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocMeasurementResultsReceived, 
       
  2247 											 iFsm->MeasurementInfoError());
       
  2248 				SetExitState();	
       
  2249 				}
       
  2250 			break;
       
  2251 			}
       
  2252 		}
       
  2253 	}
       
  2254 
       
  2255 /** Callback when a GPS measurement results update arrives from AGPS manager.
       
  2256 
       
  2257 Only location requests that are 'hybrid' or 'terminal assisted' should record 
       
  2258 the measurement results. Other types of request (autonomous, terminal based)
       
  2259 are only interested in the GPS position update.
       
  2260 */
       
  2261 void CLbsPrivLocWaitLocUpdateState::OnNetLocReferenceUpdate(
       
  2262 		const TLbsNetSessionIdInt& aSessionId, 
       
  2263 		const TPositionInfoBase& aPosInfo)
       
  2264 	{
       
  2265 	CLbsPrivLocStateBase::OnNetLocReferenceUpdate(aSessionId,aPosInfo);
       
  2266 	}
       
  2267 
       
  2268 
       
  2269 // ----------------------------------------------------------------------------- 
       
  2270 // 
       
  2271 // ----------------------- Class CLbsPrivLocWaitLocReqState --------------------
       
  2272 //
       
  2273 // Implements the Wait For Location Request state of the Privacy and Location 
       
  2274 // Request Handler
       
  2275 //
       
  2276 // ----------------------------------------------------------------------------- 
       
  2277 //
       
  2278 CLbsPrivLocWaitLocReqState* CLbsPrivLocWaitLocReqState::NewL(CLbsPrivLocFsm* aFsm)
       
  2279 	{
       
  2280 	return new(ELeave)CLbsPrivLocWaitLocReqState(aFsm);
       
  2281 	}
       
  2282 	
       
  2283 CLbsPrivLocWaitLocReqState::CLbsPrivLocWaitLocReqState(CLbsPrivLocFsm* aFsm)	
       
  2284 : CLbsPrivLocStateBase(aFsm)
       
  2285 	{
       
  2286 	}
       
  2287 
       
  2288 // ----------------------------------------------------------------------------- 
       
  2289 // CLbsPrivLocWaitLocReqState::OnEntry
       
  2290 // Description: Carries out tasks required on entry to the state.
       
  2291 // ----------------------------------------------------------------------------- 
       
  2292 //
       
  2293 void CLbsPrivLocWaitLocReqState::OnEntry(const TPrivLocCommonParams& aStateParams)
       
  2294 	{
       
  2295 	CLbsPrivLocStateBase::OnEntry(aStateParams);
       
  2296 	const TPrivLocWaitLocationRequestParams& params = TPrivLocWaitLocationRequestParams::Cast(aStateParams);	
       
  2297 	iFsm->IsEmergency() = params.iIsEmergency;
       
  2298 	iFsm->PrivacyRequestCancelled() = params.iReqCancelled;
       
  2299 	iFsm->PreviousStateExitInfo() = params.iPreviousStateExitInfo;
       
  2300 	}
       
  2301 
       
  2302 	
       
  2303 // ----------------------------------------------------------------------------- 
       
  2304 // CLbsPrivLocWaitLocReqState::OnExit
       
  2305 // Description: Carries out tasks required on exit from the state.
       
  2306 // Panics if the exit reason is not handled by the base state exit
       
  2307 // ----------------------------------------------------------------------------- 
       
  2308 //
       
  2309 TBool CLbsPrivLocWaitLocReqState::OnExit()
       
  2310 	{
       
  2311 	TBool consumed = CLbsPrivLocStateBase::OnExit();
       
  2312 	// If the exit reason wasn't handled, panic (should only happen in development)
       
  2313 	__ASSERT_DEBUG(consumed, Panic(ENrhPanicWaitLocReqUnknownExitReason));
       
  2314 	return(consumed);
       
  2315 	}
       
  2316 
       
  2317 void CLbsPrivLocWaitLocReqState::OnMTLRRequest(const TLbsNetSessionIdInt& /*aSessionId*/,
       
  2318 					   TLbsNetworkEnumInt::TLbsNetProtocolServiceInt /*aSessionType*/, 
       
  2319 					   TBool /*aIsEmergency*/,
       
  2320 					   const TLbsExternalRequestInfo& /*aExternalRequestInfo*/,
       
  2321 					   const TLbsNetPosRequestPrivacyInt& /*aNetPosRequestPrivacy*/)
       
  2322 	{
       
  2323 	// this can never happen. If the Fsm is in the WaitLocReqState then 
       
  2324 	// any arrival of a MTLR request would start a new session and the OnMTLRRequest()
       
  2325 	// would be directed to that session not this one
       
  2326 	__ASSERT_DEBUG(EFalse, Panic(ENrhPanicBadParamType)); 
       
  2327 	}
       
  2328 	
       
  2329 void CLbsPrivLocWaitLocReqState::OnNetLocRequest(const TLbsNetSessionIdInt& aSessionId, 
       
  2330 						const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
  2331 						 TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
  2332 						 TBool aIsEmergency,
       
  2333 						 const TLbsNetPosRequestQualityInt& aQuality)
       
  2334 	{
       
  2335 	TInt numMethods = aPosRequestMethod.NumPosMethods();
       
  2336 	if (numMethods==1)
       
  2337 		{
       
  2338 		TLbsNetPosMethodInt netPosMethod;
       
  2339 		aPosRequestMethod.GetPosMethod(0,netPosMethod);
       
  2340 				
       
  2341 		if (netPosMethod.PosMode()== (TPositionModuleInfo::ETechnologyNetwork | TPositionModuleInfo::ETechnologyAssisted))
       
  2342 			{
       
  2343 			iFsm->TapMode() = ETrue;
       
  2344 			}
       
  2345 		}
       
  2346 	
       
  2347 	
       
  2348 	if(aSessionId == iFsm->SessionId())
       
  2349 		{
       
  2350 		if (iFsm->PrivacyRequestCancelled())
       
  2351 			{
       
  2352 			iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitCancelledByPrivacyController, KErrCancel);
       
  2353 			TPrivLocWaitLocationRequestParams locationRequestParams(iFsm->SessionId(), 
       
  2354 																	iFsm->IsEmergency(), 
       
  2355 																	iFsm->PrivacyRequestCancelled());
       
  2356 			iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationRequest, locationRequestParams);
       
  2357 			}
       
  2358 		else
       
  2359 			{
       
  2360 			iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitLocReqReceived, KErrNone);
       
  2361 			TPrivLocWaitLocationUpdateParams updateRequestParams(aSessionId,
       
  2362 																 aPosRequestMethod,
       
  2363 																 aSessionType,
       
  2364 																 aIsEmergency,
       
  2365 																 aQuality);
       
  2366 			iFsm->ChangeState(CLbsPrivLocFsm::EStateWaitLocationUpdate, updateRequestParams);
       
  2367 			}
       
  2368 		}
       
  2369 	else
       
  2370 		{
       
  2371 		HandleLocRequest(aSessionId,aPosRequestMethod,
       
  2372 							aSessionType,aIsEmergency,
       
  2373 							aQuality);
       
  2374 		}
       
  2375 	}
       
  2376 
       
  2377 void CLbsPrivLocWaitLocReqState::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aSessionId)
       
  2378 	{
       
  2379 	if (!iFsm->IsEmergency() && (aSessionId == iFsm->SessionId()))
       
  2380 			{
       
  2381 			if (!iFsm->PrivacyRequestCancelled() )
       
  2382 				{
       
  2383 				TLbsNetSessionIdInt sessionId = iFsm->SessionId();
       
  2384 				MessageSwitch()->SendExternalLocateCancel(sessionId,KErrCancel);
       
  2385 				}
       
  2386 			iFsm->PrivacyRequestCancelled() = ETrue;
       
  2387 			}
       
  2388 	}
       
  2389 
       
  2390 
       
  2391 /** Called when a reference position arrives from the network.
       
  2392 */
       
  2393 void CLbsPrivLocWaitLocReqState::OnNetLocReferenceUpdate(
       
  2394 		const TLbsNetSessionIdInt& aSessionId, 
       
  2395 		const TPositionInfoBase& aPosInfo)
       
  2396 	{
       
  2397 	// if the MTLR is still active (has not been cancelled by the privacy handler)
       
  2398 	if (!iFsm->PrivacyRequestCancelled())
       
  2399 		{
       
  2400 		CLbsPrivLocStateBase::OnNetLocReferenceUpdate(aSessionId, aPosInfo);
       
  2401 		}	
       
  2402 	}
       
  2403 
       
  2404 // ----------------------------------------------------------------------------- 
       
  2405 // CLbsPrivLocWaitLocReqState::OnSessionComplete
       
  2406 // Description: handling of a session complete message
       
  2407 // ----------------------------------------------------------------------------- 
       
  2408 //
       
  2409 void CLbsPrivLocWaitLocReqState::OnSessionComplete(const TLbsNetSessionIdInt& aSessionId,
       
  2410 																TInt aReason)
       
  2411 	{
       
  2412 	
       
  2413 	
       
  2414 	if(aSessionId == iFsm->SessionId())
       
  2415 		{
       
  2416 		// Make sure the reason passed with the Session Complete is sent to the
       
  2417  		// Privacy Controller EXCEPT when the update previously passed to the 
       
  2418  		// network didn't meet the quality criteria. In this case use the
       
  2419  		// KPositionQualityLoss status.
       
  2420 		TInt completionReason = aReason;
       
  2421 		if(aReason == KErrNone)
       
  2422  			{
       
  2423  			if(KPositionQualityLoss == iFsm->PreviousStateExitInfo())
       
  2424  				{
       
  2425  				completionReason = KPositionQualityLoss;
       
  2426  				}
       
  2427  			}
       
  2428 		
       
  2429 		iFsm->ExitData().SetExitData(TPrivLocStateExitData::EExitSessionComplete, completionReason);
       
  2430 		iFsm->ChangeState(CLbsPrivLocFsm::EStateIdle, aSessionId);	            
       
  2431 		}		
       
  2432 	}
       
  2433 
       
  2434 // ----------------------------------------------------------------------------- 
       
  2435 //
       
  2436 // Package classes
       
  2437 //
       
  2438 // ----------------------------------------------------------------------------- 
       
  2439 //
       
  2440 TPrivLocCommonParams::TPrivLocCommonParams()
       
  2441 	{	
       
  2442 	}
       
  2443 TPrivLocCommonParams::TPrivLocCommonParams(TLbsNetSessionIdInt aSessionId)
       
  2444 	{
       
  2445 	iSessionId = aSessionId;												
       
  2446 	}
       
  2447 
       
  2448 TPrivLocWaitLocationRequestParams::TPrivLocWaitLocationRequestParams()
       
  2449 	{
       
  2450 	}
       
  2451 TPrivLocWaitLocationRequestParams::TPrivLocWaitLocationRequestParams(
       
  2452 			const TLbsNetSessionIdInt& aSessionId,
       
  2453 			TBool	aIsEmergency,
       
  2454 			TBool   aReqCancelled,
       
  2455 			TInt    aPreviousStateExitInfo) :
       
  2456 	TPrivLocCommonParams(aSessionId),
       
  2457 	iIsEmergency(aIsEmergency),
       
  2458 	iReqCancelled(aReqCancelled),
       
  2459 	iPreviousStateExitInfo(aPreviousStateExitInfo)
       
  2460 	{
       
  2461 	}
       
  2462 
       
  2463 TPrivLocWaitLocationUpdateParams::TPrivLocWaitLocationUpdateParams()
       
  2464 	{	
       
  2465 	}
       
  2466 TPrivLocWaitLocationUpdateParams::TPrivLocWaitLocationUpdateParams(
       
  2467 			const TLbsNetSessionIdInt& aSessionId,
       
  2468 			const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
  2469 			TLbsNetworkEnumInt::TLbsNetProtocolServiceInt  aSessionType,
       
  2470 			TBool aIsEmergency,
       
  2471 			const TLbsNetPosRequestQualityInt& aQuality) :
       
  2472 	TPrivLocCommonParams(aSessionId),
       
  2473 	iSessionType(aSessionType),
       
  2474 	iIsEmergency(aIsEmergency),
       
  2475 	iQuality(aQuality),
       
  2476 	iPosRequestMethod(aPosRequestMethod)
       
  2477 	{
       
  2478 	}
       
  2479 
       
  2480 TPrivLocWaitPrivResponseParams::TPrivLocWaitPrivResponseParams()
       
  2481 	{
       
  2482 	
       
  2483 	}
       
  2484 TPrivLocWaitPrivResponseParams::TPrivLocWaitPrivResponseParams(
       
  2485 			const TLbsNetSessionIdInt& aSessionId,
       
  2486 			const TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType,
       
  2487 			const TLbsExternalRequestInfo& aExternalRequestInfo,
       
  2488 			const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy,
       
  2489 			TBool aIsEmergency) :
       
  2490 	TPrivLocCommonParams(aSessionId),
       
  2491 	iNetPosRequestPrivacy(aNetPosRequestPrivacy),
       
  2492 	iIsEmergency(aIsEmergency),
       
  2493 	iSessionType(aSessionType)
       
  2494 	{
       
  2495 	// Need to check the type of aExternalRequestInfo before 
       
  2496 	// copying it into this class.
       
  2497 	if (aExternalRequestInfo.ClassType() == EExternalRequestInfoClass)
       
  2498 		{
       
  2499 		__ASSERT_DEBUG(aExternalRequestInfo.ClassSize() == sizeof(TLbsExternalRequestInfo), 
       
  2500 					   Panic(ENrhPanicInvalidExternalRequestInfoType));
       
  2501 		
       
  2502 		Mem::Copy(&iExternalRequestInfo, 
       
  2503 				  &aExternalRequestInfo, 
       
  2504 				  sizeof(TLbsExternalRequestInfo));
       
  2505 		}
       
  2506 	else 
       
  2507 		{
       
  2508 		if (aExternalRequestInfo.ClassType() == (EExternalRequestInfoClass | EExternalRequestInfoClass2))
       
  2509 			{
       
  2510 			__ASSERT_DEBUG(aExternalRequestInfo.ClassSize() == sizeof(TLbsExternalRequestInfo2), 
       
  2511 						   Panic(ENrhPanicInvalidExternalRequestInfoType));
       
  2512 
       
  2513 			Mem::Copy(&iExternalRequestInfo, 
       
  2514 					  &aExternalRequestInfo, 
       
  2515 					  sizeof(TLbsExternalRequestInfo2));
       
  2516 			}
       
  2517 		else
       
  2518 			{
       
  2519 			Panic(ENrhPanicInvalidExternalRequestInfoType);
       
  2520 			}
       
  2521 		}
       
  2522 	}
       
  2523 
       
  2524 // ----------------------------------------------------------------------------- 
       
  2525 // 
       
  2526 // ----------------------------- Class CLbsPrivLocFsm --------------------------
       
  2527 //
       
  2528 // State Machine class which owns the states of the Privacy and Location Handler
       
  2529 //
       
  2530 // ----------------------------------------------------------------------------- 
       
  2531 //
       
  2532 
       
  2533 // ----------------------------------------------------------------------------- 
       
  2534 // CLbsPrivLocFsm::NewL
       
  2535 // Description: CLbsPrivLocFsm static constructor 
       
  2536 // ----------------------------------------------------------------------------- 
       
  2537 //
       
  2538 CLbsPrivLocFsm* CLbsPrivLocFsm::NewL(
       
  2539 		CPrivacyAndLocationHandler& aPrivLocHandler,
       
  2540 		const TLbsNetSessionIdInt& aSessionId)
       
  2541 	{
       
  2542 	CLbsPrivLocFsm* self; 
       
  2543 	self = new (ELeave) CLbsPrivLocFsm(aPrivLocHandler, aSessionId);
       
  2544 	CleanupStack::PushL(self);
       
  2545 	self->ConstructL();
       
  2546 	CleanupStack::Pop(self);
       
  2547 	return(self);	
       
  2548 	}
       
  2549 
       
  2550 // ----------------------------------------------------------------------------- 
       
  2551 // CLbsPrivLocFsm::CLbsPrivLocFsm
       
  2552 // Description: CLbsPrivLocFsm constructor 
       
  2553 // ----------------------------------------------------------------------------- 
       
  2554 //
       
  2555 CLbsPrivLocFsm::CLbsPrivLocFsm(
       
  2556 		CPrivacyAndLocationHandler& aPrivLocHandler,
       
  2557 		const TLbsNetSessionIdInt& aSessionId) :
       
  2558 	iPrivLocHandler(aPrivLocHandler),
       
  2559 	iSessionId(aSessionId),
       
  2560 	iIsEmergency(EFalse),
       
  2561 	iSessionType(TLbsNetworkEnumInt::EServiceNone),
       
  2562 	iRefPosProcessed(EFalse),
       
  2563 	iLocReqReceived(EFalse),
       
  2564 	iReqCancelled(EFalse),
       
  2565 	iWasPrivacyResponseReceivedStateExited(EFalse),
       
  2566 	iPositioningStatusIncremented(EFalse)
       
  2567 	{	
       
  2568 	}
       
  2569 	
       
  2570 // ----------------------------------------------------------------------------- 
       
  2571 // CLbsPrivLocFsm::~CLbsPrivLocFsm
       
  2572 // Description: CLbsPrivLocFsm destructor 
       
  2573 // ----------------------------------------------------------------------------- 
       
  2574 //
       
  2575 CLbsPrivLocFsm::~CLbsPrivLocFsm()
       
  2576 	{
       
  2577 	delete iLocationUpdateTimer;
       
  2578 	iStates.DeleteAll();
       
  2579 	iStates.Reset();
       
  2580 	}
       
  2581 
       
  2582 // ----------------------------------------------------------------------------- 
       
  2583 // CLbsPrivLocFsm::SessionId
       
  2584 // Description: Get the current session Id for this FSM.
       
  2585 // ----------------------------------------------------------------------------- 
       
  2586 //
       
  2587 const TLbsNetSessionIdInt& CLbsPrivLocFsm::SessionId() const
       
  2588 	{
       
  2589 	return iSessionId;
       
  2590 	}
       
  2591 
       
  2592 // ----------------------------------------------------------------------------- 
       
  2593 // CLbsPrivLocFsm::ConstructL
       
  2594 // Description: CLbsPrivLocFsm second-phase constructor.
       
  2595 //              Creates the states of the system and the Privacy Handler.
       
  2596 // ----------------------------------------------------------------------------- 
       
  2597 //
       
  2598 void CLbsPrivLocFsm::ConstructL()
       
  2599 	{
       
  2600 	// Create the states
       
  2601 	iStates.At(EStateIdle) = CLbsPrivLocIdleState::NewL(this);
       
  2602 	iStates.At(EStateWaitPrivacyResponse) = CLbsPrivLocWaitPrivRespState::NewL(this);
       
  2603 	iStates.At(EStateWaitLocationRequest) = CLbsPrivLocWaitLocReqState::NewL(this);
       
  2604 	iStates.At(EStateWaitLocationUpdate) = CLbsPrivLocWaitLocUpdateState::NewL(this);
       
  2605 
       
  2606 	iCurrentState = iStates.At(EStateIdle);
       
  2607     // When waiting for an update, there is a maximum duration specified by the
       
  2608     // LBS admin data to avoid the risk of hanging around forever in the event of 
       
  2609     // a problem with the A-GPS module. Create a timer to deal with this.
       
  2610     iLocationUpdateTimer = CLbsCallbackTimer::NewL(*this);
       
  2611 	}
       
  2612 	
       
  2613 	
       
  2614 TBool CLbsPrivLocFsm::IsSpecialFeatureIntermediateFutileUpdateOn()
       
  2615 	{
       
  2616 	return PrivLocHandler().IsSpecialFeatureIntermediateFutileUpdateOn();
       
  2617 	}
       
  2618 
       
  2619 // ----------------------------------------------------------------------------- 
       
  2620 // CPrivacyAndLocationHandler::SetServerObserver
       
  2621 // Description: Store a pointer to the NRH server which comunicates with the 
       
  2622 // Privacy Controller.
       
  2623 // ----------------------------------------------------------------------------- 
       
  2624 //
       
  2625 void CLbsPrivLocFsm::SetServerObserver(MLbsSessionObserver* aNrhServer)
       
  2626     {
       
  2627     PrivLocHandler().PrivacyHandler()->SetServerObserver(aNrhServer);
       
  2628     }
       
  2629 
       
  2630 // ----------------------------------------------------------------------------- 
       
  2631 // CLbsPrivLocFsm::OnRespondNetworkLocationRequest
       
  2632 // Description: Called by the Privacy Handler to report the result of a privacy
       
  2633 // check. Handling of the response is delegated to the current state.
       
  2634 // ----------------------------------------------------------------------------- 
       
  2635 //
       
  2636 void CLbsPrivLocFsm::OnRespondNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId, 
       
  2637                             TLbsNetworkEnumInt::TLbsPrivacyResponseInt aRequestResult,
       
  2638                             TInt aResponseReason)
       
  2639 	{
       
  2640 	LBSLOG3(ELogP3, "FSM(%d) OnRespondNetworkLocationRequest response=%d",iSessionId.SessionNum(),aRequestResult);
       
  2641 	iCurrentState->OnRespondNetworkLocationRequest(aRequestId, aRequestResult, aResponseReason);
       
  2642     }
       
  2643 
       
  2644 // ----------------------------------------------------------------------------- 
       
  2645 // CLbsPrivLocFsm::OnCancelNetworkLocationRequest
       
  2646 // Description: Called by the Privacy Handler to report that a privacy check 
       
  2647 // has been rejected. This may occur after it has already been accepted.
       
  2648 // Handling of the response is delegated to the current state.
       
  2649 // ----------------------------------------------------------------------------- 
       
  2650 //
       
  2651 void CLbsPrivLocFsm::OnCancelNetworkLocationRequest(const TLbsNetSessionIdInt& aRequestId)
       
  2652     {
       
  2653 	LBSLOG2(ELogP3, "FSM(%d) OnCancelNetworkLocationRequest",iSessionId.SessionNum());
       
  2654 	iCurrentState->OnCancelNetworkLocationRequest(aRequestId);
       
  2655     }
       
  2656 
       
  2657 // ----------------------------------------------------------------------------- 
       
  2658 // CLbsPrivLocFsm::OnMTLRRequest
       
  2659 // Description: The Message Switch has forwarded a request to start an MTLR 
       
  2660 // session.
       
  2661 // Handling of the request is delegated to the current state.
       
  2662 // ----------------------------------------------------------------------------- 
       
  2663 //
       
  2664 void CLbsPrivLocFsm::OnMTLRRequest(const TLbsNetSessionIdInt& aSessionId,
       
  2665 					   TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
  2666 					   TBool aIsEmergency,
       
  2667 					   const TLbsExternalRequestInfo& aExternalRequestInfo,
       
  2668 					   const TLbsNetPosRequestPrivacyInt& aNetPosRequestPrivacy)
       
  2669 	{
       
  2670 	LBSLOG2(ELogP3, "FSM(%d) OnMTLRRequest",iSessionId.SessionNum());
       
  2671 	iCurrentState->OnMTLRRequest(aSessionId, 
       
  2672 								aSessionType, 
       
  2673 								aIsEmergency, 
       
  2674 								aExternalRequestInfo, 
       
  2675 								aNetPosRequestPrivacy);
       
  2676 	}
       
  2677 	
       
  2678 // ----------------------------------------------------------------------------- 
       
  2679 // CLbsPrivLocFsm::OnSessionComplete
       
  2680 // Description: The Message Switch has reported that the session is
       
  2681 // over (complete or aborted due to some error).
       
  2682 // Handling of the message is delegated to the current state.
       
  2683 // ----------------------------------------------------------------------------- 
       
  2684 //
       
  2685 void CLbsPrivLocFsm::OnSessionComplete(
       
  2686 									const TLbsNetSessionIdInt& aSessionId,
       
  2687 									TInt aReason)
       
  2688 	{
       
  2689 	LBSLOG3(ELogP3, "FSM(%d) OnSessionComplete reason=%d",iSessionId.SessionNum(),aReason);
       
  2690 	iCurrentState->OnSessionComplete(aSessionId, aReason);
       
  2691 	
       
  2692     // update the positioning status. Note this is updated only if it was previously
       
  2693     // incremented as a result of this session.
       
  2694     if (WasPositioningStatusIncremented())
       
  2695         {
       
  2696         PrivLocHandler().DecrementPositioningStatus();
       
  2697         WasPositioningStatusIncremented() = EFalse;
       
  2698         }
       
  2699 	}
       
  2700 
       
  2701 // ----------------------------------------------------------------------------- 
       
  2702 // CLbsPrivLocFsm::OnNetLocRequest
       
  2703 // Description: The Message Switch has passed on a request for a position update
       
  2704 // Handling of the request is delegated to the current state.
       
  2705 // ----------------------------------------------------------------------------- 
       
  2706 //
       
  2707 void CLbsPrivLocFsm::OnNetLocRequest(
       
  2708 						const TLbsNetSessionIdInt& aSessionId, 
       
  2709 						const TLbsNetPosRequestMethodInt& aPosRequestMethod,
       
  2710 						TLbsNetworkEnumInt::TLbsNetProtocolServiceInt aSessionType, 
       
  2711 						TBool aIsEmergency,
       
  2712 						const TLbsNetPosRequestQualityInt& aQuality)
       
  2713 	{
       
  2714 	LBSLOG2(ELogP3, "FSM(%d) OnNetLocRequest",iSessionId.SessionNum());
       
  2715 	iCurrentState->OnNetLocRequest(aSessionId,
       
  2716 	 					aPosRequestMethod, 
       
  2717 	 					aSessionType, 
       
  2718 						aIsEmergency, 
       
  2719 						aQuality);
       
  2720 	}
       
  2721 
       
  2722 /** Called when a reference position arrives from the network.
       
  2723 */
       
  2724 void CLbsPrivLocFsm::OnNetLocReferenceUpdate(
       
  2725 		const TLbsNetSessionIdInt& aSessionId, 
       
  2726 		const TPositionInfoBase& aPosInfo)
       
  2727 	{
       
  2728 	LBSLOG2(ELogP3, "FSM(%d) OnNetLocReferenceUpdate",iSessionId.SessionNum());
       
  2729 	iCurrentState->OnNetLocReferenceUpdate(aSessionId, aPosInfo);	
       
  2730 	}
       
  2731 
       
  2732 /** Callend when a final location arrives from the network.
       
  2733 
       
  2734 Currently the final network position is never used by the 
       
  2735 state machine - it is only needed by the X3P handler. 
       
  2736 So this function just ignores the update.
       
  2737 */
       
  2738 void CLbsPrivLocFsm::OnNetLocFinalUpdate(
       
  2739 		const TLbsNetSessionIdInt& /*aSessionId*/, 
       
  2740 		const TPositionInfoBase& /*aPosInfo*/)
       
  2741 	{
       
  2742 	// Final network position not used by CLbsPrivLocFsm, so ignore it.
       
  2743 	}
       
  2744 
       
  2745 // ----------------------------------------------------------------------------- 
       
  2746 // CLbsPrivLocFsm::ChangeState
       
  2747 // Description: Called by a state of the FSM when a transition is required.
       
  2748 // ----------------------------------------------------------------------------- 
       
  2749 //
       
  2750 void CLbsPrivLocFsm::ChangeState(TLocPrivacyHandlerState aNewStateId,const TPrivLocCommonParams& aStateParams)
       
  2751 	{
       
  2752 	// Tidy up the old state
       
  2753 	if(iCurrentState)
       
  2754 		{
       
  2755 		// coverity[unchecked_value]
       
  2756 		// We're not interested in whether it was consumed here
       
  2757 		iCurrentState->OnExit();
       
  2758 		}
       
  2759 
       
  2760 	// Note, here the session ID has already being set when the Fsm was created (when session first came into being)
       
  2761 	// so no need to do this ... iSessionId = aStateParams.iSessionId;
       
  2762 
       
  2763 	// Set the new state
       
  2764 	iCurrentState = iStates.At(aNewStateId);
       
  2765 
       
  2766 	LBSLOG3(ELogP3, "FSM(%d) Entering state %d",iSessionId.SessionNum(), aNewStateId);
       
  2767 	
       
  2768 	// Do any initialisation for the new state.
       
  2769 	iCurrentState->OnEntry(aStateParams);
       
  2770 	}
       
  2771 
       
  2772 // ----------------------------------------------------------------------------- 
       
  2773 // CLbsPrivLocFsm::ChangeState
       
  2774 // Description: Called by a state of the FSM when a transition is required to a 
       
  2775 // state which only requires the session Id
       
  2776 // ----------------------------------------------------------------------------- 
       
  2777 //
       
  2778 void CLbsPrivLocFsm::ChangeState(TLocPrivacyHandlerState aNewStateId,
       
  2779 											const TLbsNetSessionIdInt& aSessionId)
       
  2780 	{
       
  2781 	TPrivLocCommonParams commonParams(aSessionId);
       
  2782 	ChangeState(aNewStateId, commonParams);
       
  2783 	}
       
  2784 
       
  2785 // ----------------------------------------------------------------------------- 
       
  2786 // CLbsPrivLocFsm::PrivLocHandler
       
  2787 // Description: Get the CPrivacyAndLocationHandler object
       
  2788 // ----------------------------------------------------------------------------- 
       
  2789 //
       
  2790 CPrivacyAndLocationHandler& CLbsPrivLocFsm::PrivLocHandler()
       
  2791 	{
       
  2792 	return iPrivLocHandler;
       
  2793 	}
       
  2794 
       
  2795 // ----------------------------------------------------------------------------- 
       
  2796 // CLbsPrivLocWaitLocUpdateState::OnTimerEventL
       
  2797 // Description: The Location Update timer has expired.
       
  2798 // Cancel the request, and pass on the response if any has been received,
       
  2799 // otherwise report failure.
       
  2800 // ----------------------------------------------------------------------------- 
       
  2801 //
       
  2802 void CLbsPrivLocFsm::OnTimerEventL(TInt aTimerId)
       
  2803 	{	
       
  2804 	LBSLOG2(ELogP3, "FSM(%d) OnTimerEventL", iSessionId.SessionNum());
       
  2805 	iCurrentState->OnTimerEventL(aTimerId);
       
  2806 	}
       
  2807 
       
  2808 /** Called if OnTimerEventL leaves */
       
  2809 TInt CLbsPrivLocFsm::OnTimerError(TInt /*aTimerId*/, TInt aError)
       
  2810 	{
       
  2811 	__ASSERT_DEBUG(EFalse, Panic(ENrhPanicLocationTimerError));
       
  2812 	return(aError);
       
  2813 	}
       
  2814 
       
  2815 /** Callback when a GPS position update arrives from AGPS manager.
       
  2816 */
       
  2817 void CLbsPrivLocFsm::OnAgpsPositionUpdate(
       
  2818 	TInt aReason,
       
  2819 	const TPositionExtendedSatelliteInfo& aPosInfo,
       
  2820 	const TTime& aTimeStamp)
       
  2821 	{
       
  2822 	LBSLOG2(ELogP3, "FSM(%d) OnAgpsPositionUpdate", iSessionId.SessionNum());
       
  2823 	iCurrentState->OnAgpsPositionUpdate(aReason, aPosInfo, aTimeStamp);
       
  2824 	}
       
  2825 
       
  2826 /** Callback when a GPS measurement results update arrives from AGPS manager.
       
  2827 */
       
  2828 void CLbsPrivLocFsm::OnAgpsMeasurementUpdate(
       
  2829 	TInt aReason,
       
  2830 	const TPositionGpsMeasurementInfo& aPosInfo,
       
  2831 	const TTime& aTimeStamp)
       
  2832 	{
       
  2833 	LBSLOG2(ELogP3, "FSM(%d) OnAgpsMeasurementUpdate", iSessionId.SessionNum());
       
  2834 	iCurrentState->OnAgpsMeasurementUpdate(aReason, aPosInfo, aTimeStamp);
       
  2835 	}