networkprotocolmodules/suplprotocolmodule/SuplProtocol/src/suplmtlrfsmsession.cpp
changeset 36 b47902b73a93
parent 0 9cfd9a3ee49c
equal deleted inserted replaced
35:a2efdd544abf 36:b47902b73a93
       
     1 // Copyright (c) 2008-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 // This file provides the implementation of the class for
       
    15 // the MT-LR protocol state machine.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @deprecated
       
    23 */
       
    24 
       
    25 #include "suplmtlrfsmsession.h"
       
    26 #include "suplmtlrstatehandler.h"
       
    27 #include "suplrrlpstatemachine.h"
       
    28 #include "suplend.h"
       
    29 #include "suplinit.h"
       
    30 #include "supldevloggermacros.h"
       
    31 #include "suplgatewayinterface.h"
       
    32 
       
    33 
       
    34 /** KMaxQueueEntry
       
    35 Maximum number of messages waiting to be processed
       
    36 in the state machine event store.
       
    37 */
       
    38 const TInt KMaxQueueEntry = 5;
       
    39 
       
    40 
       
    41 /** Static constructor.
       
    42 @param aObserver Reference to state machine observer.
       
    43 @return A new instance of the CSuplMtlrFsmSession class
       
    44 */
       
    45 CSuplMtlrFsmSession* CSuplMtlrFsmSession::NewL(MSuplFsmSessionObserver& aObserver)
       
    46 	{
       
    47 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::NewL() Begin\n");
       
    48 	CSuplMtlrFsmSession* self = new (ELeave) CSuplMtlrFsmSession(aObserver);
       
    49 	CleanupStack::PushL(self);
       
    50 	self->ConstructL();
       
    51 	CleanupStack::Pop(self);
       
    52 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::NewL() End\n");
       
    53 	return self;
       
    54 	}
       
    55 
       
    56 /** Standard constructor.
       
    57 @param aObserver Reference to state machine observer.
       
    58 */  
       
    59 CSuplMtlrFsmSession::CSuplMtlrFsmSession(MSuplFsmSessionObserver& aObserver)
       
    60 :CSuplFsmSessionBase(aObserver)
       
    61 	{ 
       
    62 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::CSuplMtlrFsmSession() Begin\n");
       
    63 	iLocReqType = MLbsNetworkProtocolObserver::EServiceMobileTerminated;
       
    64 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::CSuplMtlrFsmSession() End\n");
       
    65 	}
       
    66 
       
    67 
       
    68 /** Standard destructor.
       
    69 */ 
       
    70 CSuplMtlrFsmSession::~CSuplMtlrFsmSession()
       
    71 	{
       
    72 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::~CSuplMtlrFsmSession() Begin\n");
       
    73 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::~CSuplMtlrFsmSession() End\n");
       
    74 	}
       
    75 
       
    76 /** Private second-stage constructor.
       
    77 */  
       
    78 void CSuplMtlrFsmSession::ConstructL()
       
    79 	{
       
    80 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::ConstructL() Begin\n");
       
    81 	CActiveScheduler::Add(this);
       
    82 
       
    83 	iEventStore = CSuplFsmEventStore::NewL(KMaxQueueEntry);
       
    84 
       
    85 	// Create state handler
       
    86 	iStateHandler = CSuplMtLrStateHandler::NewL(*this);
       
    87 
       
    88 	// Open up assistance data builder
       
    89 	iAssistanceDataBuilderSet.OpenL();
       
    90 
       
    91 	// Create a Positioning Protocol State Machine
       
    92 	iPositioningProtocol = CSuplRrlpFsm::NewL(*this,iAssistanceDataBuilderSet);
       
    93 	
       
    94 	// Create timers used during MTLR protocol procedure
       
    95 	iSuplProtTimer = CLbsCallbackTimer::NewL(*this);
       
    96 	
       
    97 	iSlpSettingsStore = CLbsHostSettingsStore::NewL(KLbsHostSettingsSuplStoreId);
       
    98 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::ConstructL() End\n");
       
    99 	}
       
   100 
       
   101 /** GetHostId()
       
   102 This method returns the ID of an entry in the HostSettings store
       
   103 containing the address of the host (SLP) to connect to.
       
   104 For MTLR, and in accordance with the SUPL specifications, only
       
   105 a host that has been provisioned by the home network will be used.
       
   106 This method retrieves the network-provisioned host that has last
       
   107 been modified.
       
   108 @param aHostId the ID of the host selected for the MTLR
       
   109 @return KErrNone if a valid host ID has been found
       
   110 */
       
   111 TInt CSuplMtlrFsmSession::GetHostId(TLbsHostSettingsId& aHostId)
       
   112 	{
       
   113 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::GetHostId() Begin\n");
       
   114 	TInt err = KErrNotFound;
       
   115 	TBool hostFound = EFalse;
       
   116 	if (iSlpSettingsStore)
       
   117 		{
       
   118 		TLbsHostSettingsSupl slpSettings;
       
   119 		TLbsHostSettingsId 	settingsId;
       
   120 
       
   121 		// Get the network-provisioned SLP that has been 
       
   122 		// modified most recently
       
   123 		TTime mostRecent = 0;
       
   124 		err = iSlpSettingsStore->RewindHostSettings();
       
   125 		if (KErrNone == err)
       
   126 			{
       
   127 			while (KErrNone == err)
       
   128 				{
       
   129 				err = iSlpSettingsStore->GetNextHostSettingsByCreator(KLbsHostSettingsDevProvCreatorId, slpSettings, settingsId);		
       
   130 				if (KErrNone == err)
       
   131 					{
       
   132 					if (mostRecent < slpSettings.LastModified())
       
   133 						{
       
   134 						mostRecent = slpSettings.LastModified();
       
   135 						aHostId = settingsId;
       
   136 						hostFound = ETrue;
       
   137 						}
       
   138 					}
       
   139 				}
       
   140 			}			
       
   141 		}	
       
   142 
       
   143 	if(!hostFound)
       
   144 		{
       
   145 		SUPLLOG(ELogP1, "CSuplMtlrFsmSession::GetHostId(), GenerateHostId() End\n");
       
   146 		return GenerateHostId(aHostId);
       
   147 		}
       
   148 
       
   149 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::GetHostId() End\n");
       
   150 	// If we did not return earlier, we must have found a valid ID
       
   151 	return KErrNone;
       
   152 	}
       
   153 
       
   154 
       
   155 /** Initialise internal state attributes.
       
   156 This is used when new MTLR procedure commences.
       
   157 */
       
   158 void CSuplMtlrFsmSession::InitialiseProcedure()
       
   159 	{
       
   160 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::InitialiseProcedure() Begin\n");
       
   161 	// Initialise state machine
       
   162 	InitialiseMachineBase();	
       
   163 	iCurrentState = EStateProcedureNull;
       
   164 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::InitialiseProcedure() End\n");
       
   165 	}
       
   166 	
       
   167 
       
   168 /** State transition.
       
   169 This method determines the next state to be adopted by the state machine.
       
   170 @return TBool ETrue if the state has changed.
       
   171 @param aForceRedo, indicates that the states entry action must be re-performed when there has been no change in state
       
   172 */
       
   173 TBool CSuplMtlrFsmSession::SelectNextState(TBool& aForceRedo)
       
   174 	{
       
   175 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Begin\n");
       
   176 	TBool stateChanged = ETrue;
       
   177 	aForceRedo = EFalse;
       
   178 	// Regardless of current state, check first if an event has occurred
       
   179 	// that implies cancelling the machine (terminate session)
       
   180 	if (IsCancelPending())
       
   181 		{
       
   182 		SetMachineAsCancelling();
       
   183 		iCurrentState = (IsSessionConnected() && iSessionInProgress)? EStateSuplSessionEnded : EStatePosSessionEnded;
       
   184 		}
       
   185 	else
       
   186 		{
       
   187 		// Set new state	
       
   188 		switch (iCurrentState)
       
   189 			{
       
   190 		case EStateProcedureNull:
       
   191 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStateProcedureNull\n");
       
   192 			iCurrentState = EStateSuplInitReceived;
       
   193 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateSuplInitReceived\n");
       
   194 			SetSessionInProgress(ETrue);
       
   195 			break;
       
   196 			
       
   197 		case EStateSuplInitReceived:
       
   198 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStateSuplInitReceived\n");
       
   199 			stateChanged = DetermineStateFromInitReceived();
       
   200 			break;
       
   201 
       
   202 		case EStateNetConnectionStarted:
       
   203 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStateNetConnectionStarted\n");
       
   204 			stateChanged = DetermineStateFromConnectionStarted(aForceRedo);
       
   205 			break;
       
   206 	
       
   207 		case EStatePosInitSent:
       
   208 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStatePosInitSent\n");
       
   209 			stateChanged = DetermineStateFromPosInitSent();
       
   210 			break;
       
   211 
       
   212 		case EStatePositioningInProgress:
       
   213 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStatePositioningInProgress\n");
       
   214 			stateChanged = DetermineStateFromPositioningInProgress(aForceRedo);
       
   215 			break;
       
   216 
       
   217 		case EStatePositionReceived:
       
   218 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStatePositionReceived\n");
       
   219 			iCurrentState = EStatePosSessionEnded;
       
   220 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosSessionEnded\n");
       
   221 			SetMachineAsNotCancellable();
       
   222 			break;
       
   223 			
       
   224 		case EStateSuplSessionEnded:
       
   225 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStateSuplSessionEnded\n");
       
   226 			iCurrentState = EStatePosSessionEnded;
       
   227 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateSuplSessionEnded\n");
       
   228 			break;
       
   229 
       
   230 		case EStatePosSessionEnded:
       
   231 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStatePosSessionEnded\n");
       
   232 			iCurrentState = EStateLbsSessionEnded;
       
   233 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateLbsSessionEnded\n");
       
   234 			break;
       
   235 			
       
   236 		case EStateLbsSessionEnded:
       
   237 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStateLbsSessionEnded\n");
       
   238 			iCurrentState = EStateNetConnectionClosed;
       
   239 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateNetConnectionClosed\n");
       
   240 			break;
       
   241 			
       
   242 		case EStateNetConnectionClosed:
       
   243 			SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() Entry state: EStateNetConnectionClosed\n");
       
   244 			// Procedure has completed
       
   245 			iCurrentState = EStateProcedureNull;
       
   246 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateProcedureNull\n");
       
   247 			break;
       
   248 			
       
   249 		default:
       
   250 			SUPLLOG(ELogP3, "CSuplMtlrFsmSession::SelectNextState() unknown entry state\n");
       
   251 			ASSERT(EFalse);
       
   252 			break;
       
   253 			};
       
   254 		}
       
   255 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::SelectNextState() End\n");
       
   256 	return stateChanged;
       
   257 	}
       
   258 	
       
   259 
       
   260 /** Complete the procedure.
       
   261 */  
       
   262 void CSuplMtlrFsmSession::CompleteProcedure()
       
   263 	{
       
   264 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::CompleteProcedure() Begin\n");
       
   265 	// Complete state machine
       
   266 	CompleteMachineBase();
       
   267 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::CompleteProcedure() End\n");
       
   268 	}
       
   269 	
       
   270 /** Complete a state transition.
       
   271 This is called by the base class when a state transition has
       
   272 concluded and it provides an opportunity for the state machine 
       
   273 to perform actions required immediately after this transition.
       
   274 
       
   275 The method can also initiate a further change of state. This is
       
   276 relevant when the state machine is required to perform an autonomous
       
   277 transition from one state to another e.g. this occurs when several
       
   278 interactions are required arising from a single external trigger.
       
   279 */
       
   280 void CSuplMtlrFsmSession::PostTransition()
       
   281 	{
       
   282 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PostTransition() Begin\n");
       
   283 	// Some states are transitory i.e. they require
       
   284 	// an automatic transition to the next state
       
   285 	if (IsCancelPending() ||
       
   286 		EStatePositionReceived		== iCurrentState ||
       
   287 	 	EStateSuplSessionEnded		== iCurrentState ||
       
   288 	 	EStatePosSessionEnded		== iCurrentState ||
       
   289 	 	EStateLbsSessionEnded		== iCurrentState ||
       
   290 	 	EStateNetConnectionClosed	== iCurrentState)
       
   291 		{
       
   292 		// Perform a state transition
       
   293 		PerformTransition();
       
   294 		}
       
   295 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PostTransition() End\n");
       
   296 	}
       
   297 
       
   298 
       
   299 /** Cancel the active procedure
       
   300 */  
       
   301 void CSuplMtlrFsmSession::CancelProcedure()
       
   302 	{
       
   303 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::CancelProcedure() Begin\n");
       
   304 	// Kill all timers
       
   305 	iSuplProtTimer->Cancel();
       
   306 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::CancelProcedure() End\n");
       
   307 	}
       
   308 
       
   309 
       
   310 /** Timer expired callback.
       
   311 This is called by a CStateTimer object when the timer
       
   312 has expired - the event is identified by aEvent parameter.
       
   313 @param aTimerId The timer event identifier.
       
   314 */
       
   315 void CSuplMtlrFsmSession::OnTimerEventL(TInt aTimerId)
       
   316 	{
       
   317 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::OnTimerEventL() Begin\n");
       
   318 	// Perform relevant action for the expired timer
       
   319 	switch (aTimerId)
       
   320 		{
       
   321 		
       
   322 	// Connection result timer
       
   323 	case KSessionConnectedTimerEvent:
       
   324 		CancelMachine(ECancelNetwork,EReasonTimerExpiry);
       
   325 		break;
       
   326 
       
   327 	// SUPL POS timer
       
   328 	case KSuplPosTimerEvent:
       
   329 		CancelMachine(ECancelSuplProt,EReasonTimerExpiry);
       
   330 		break;
       
   331 
       
   332 	case KSuplEndTimerEvent:
       
   333 		CancelMachine(ECancelSuplProt,EReasonTimerExpiry);
       
   334 		break;
       
   335 
       
   336 	// Ignore unknown timer events
       
   337 	default:
       
   338 		break;
       
   339 		};
       
   340 
       
   341 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::OnTimerEventL() End\n");
       
   342 	}
       
   343 
       
   344 
       
   345 /** This method stores the parameters received in a SUPL INIT message.
       
   346 If any incorrect or unsupported parameter is detected the method returns leaves. 
       
   347 */
       
   348 void CSuplMtlrFsmSession::ProcessExternalLocationRequestL(const CSuplInit* aSuplInit)
       
   349 	{
       
   350 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::StoreExternalLocationRequestL() Begin\n");
       
   351 	TLbsHostSettingsId hostId;
       
   352 	TLbsHostSettingsSupl slpSettings;
       
   353 	TLbsHostNameAddress hostNameAddress;
       
   354 	
       
   355 	// aSuplInit is constant (read-only) but
       
   356 	// access to non-constant methods is needed
       
   357 	CSuplInit* suplInitPtr = const_cast<CSuplInit*> (aSuplInit);
       
   358 	
       
   359 	// Store the Session ID
       
   360 	CSuplSessionId* sessionId = CSuplSessionId::NewL();
       
   361 	
       
   362 
       
   363 	CleanupStack::PushL(sessionId);
       
   364 	User::LeaveIfError(suplInitPtr->GetSessionId(*sessionId));
       
   365 	
       
   366 	// SLP session ID must be present
       
   367 	// SET session ID must not be present
       
   368 	if (sessionId->iSetSessionIdPresent ||
       
   369 		! sessionId->iSlpSessionIdPresent)
       
   370 		{
       
   371 		User::Leave(KErrArgument);
       
   372 		}
       
   373 	
       
   374 
       
   375 	SetMessageSessionId(sessionId);
       
   376 	CleanupStack::Pop(sessionId);
       
   377 
       
   378 	// Only proxy mode is supported
       
   379 	// (SUPL INIT with non-proxy mode is ignored)
       
   380 	CSuplInit::TSuplSlpMode slpMode = suplInitPtr->SlpMode();
       
   381 	if (CSuplInit::ESuplSlpModeProxy != slpMode)
       
   382 		{
       
   383 		User::Leave(KErrArgument);
       
   384 		}
       
   385 
       
   386 	TLbsNetPosRequestPrivacy privacy;
       
   387 	if (suplInitPtr->NotificationPresent())
       
   388 		{
       
   389 		User::LeaveIfError(suplInitPtr->GetNotificationType(privacy));
       
   390 		
       
   391 		// Check for Stealth / Privacy Override. This is not supported by LBS.
       
   392 		if (privacy.RequestAdvice() == TLbsNetPosRequestPrivacy::ERequestAdviceStealth)
       
   393 			{
       
   394 			User::Leave(KErrArgument);
       
   395 			}
       
   396 		}
       
   397 	else
       
   398 		{
       
   399 		// If notification is not present that means
       
   400 		// "no notification and no verification" as per
       
   401 		// SUPL specification (but it is up to LBS to
       
   402 		// accept such conditions depending on its configuration).	
       
   403 		privacy.SetRequestAdvice(TLbsNetPosRequestPrivacy::ERequestAdviceSilent);
       
   404 		}
       
   405 
       
   406 	//External requestor info
       
   407 	TLbsExternalRequestInfo requestInfo;
       
   408 	if (suplInitPtr->ExternalRequestInfoPresent())
       
   409 		{
       
   410 		User::LeaveIfError(suplInitPtr->GetExternalRequestInfo(requestInfo));
       
   411 		}
       
   412 
       
   413 	// QOP
       
   414 	TLbsNetPosRequestQuality quality;
       
   415 	if (suplInitPtr->QopPresent())
       
   416 		{
       
   417 		User::LeaveIfError(suplInitPtr->GetQop(quality));
       
   418 		}
       
   419 	else
       
   420 		{
       
   421 		// Set accuracy to NaN to prompt LBS to
       
   422 		// use accuracies from its pre-configured
       
   423 		// profiles if available.
       
   424 		TRealX nan;
       
   425 		nan.SetNaN();
       
   426 		quality.SetMinHorizontalAccuracy(nan);
       
   427 		quality.SetMinVerticalAccuracy(nan);
       
   428 		}
       
   429 
       
   430 	// Positioning method
       
   431 	TLbsNetPosRequestMethod method;
       
   432 	User::LeaveIfError(suplInitPtr->GetPosMethod(method));
       
   433 
       
   434 	// VER
       
   435 	User::LeaveIfError(GetHostId(hostId));
       
   436 	User::LeaveIfError(iSlpSettingsStore->GetHostSettings(hostId, slpSettings));
       
   437 	slpSettings.GetHostNameAddress(hostNameAddress);
       
   438 	TPtrC8 ver = suplInitPtr->GetVerL(hostNameAddress);
       
   439 
       
   440 	iEventStore->StoreExternalLocationRequest(privacy, requestInfo, quality, method, ver);
       
   441 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::StoreExternalLocationRequestL() End\n");
       
   442 	}
       
   443 
       
   444 
       
   445 
       
   446 //---------------------------------------------------------------------------------------------------------------------
       
   447 // --------------------------------         EVENT HANDLING METHODS          -------------------------------------------
       
   448 //---------------------------------------------------------------------------------------------------------------------
       
   449 
       
   450 //------------------------------------ EVENTS FROM PROTOCOL MANAGER  ---------------------------------------						
       
   451 
       
   452 /** Handle an MTLR request due to a SUPL INIT received.
       
   453 @param aSessionId The session ID supplied by LBS.
       
   454 @param aSuplInit The SUPL INIT that triggered the MTLR
       
   455 */
       
   456 void CSuplMtlrFsmSession::MtLrReq(const TLbsNetSessionId& aSessionId, const CSuplInit* aSuplInit)
       
   457 	{
       
   458 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::MtLrReq() Begin\n");
       
   459 	// Store parameters received in the SUPL INIT message
       
   460 	TRAPD(err, ProcessExternalLocationRequestL(aSuplInit))
       
   461 	if (KErrNone == err)
       
   462 		{
       
   463 		// Initialise the new procedure
       
   464 		InitialiseProcedure();
       
   465 		// Store the supplied ID information
       
   466 		SetSessionId(aSessionId);
       
   467 		// Perform a state transition
       
   468 		PerformTransition();
       
   469 		}
       
   470 	else
       
   471 		{
       
   472 		// A problem was found with the parameters
       
   473 		// in the SUPL INIT. Ignore the SUPL INIT
       
   474 		// and clear the event store.
       
   475 		iEventStore->ClearStore();
       
   476 		}
       
   477 
       
   478 	delete aSuplInit;
       
   479 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::MtLrReq() End\n");
       
   480 	}
       
   481 
       
   482 
       
   483 /** Handle a Response from LBS to an earlier Privacy Request
       
   484 @param aResponse Privacy response value.
       
   485 */
       
   486 void CSuplMtlrFsmSession::PrivacyResp(const TLbsNetSessionId& /*aSessionId */, 
       
   487 									  const CLbsNetworkProtocolBase::TLbsPrivacyResponse& aResponse)
       
   488 	{
       
   489 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PrivacyResp() Begin\n");
       
   490 	iEventStore->StoreEvent(aResponse);
       
   491 	// Perform a state transition out of EStateSuplInitReceived
       
   492 	// (only state expecting this event)
       
   493 	if (EStateSuplInitReceived == iCurrentState)
       
   494 		PerformTransition();
       
   495 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PrivacyResp() End\n");
       
   496 	}
       
   497 
       
   498 /** Handle LBS Location response
       
   499 @param aReason Location response error reason.
       
   500 @param aPosInfo The location information response from LBS.
       
   501 */	
       
   502 void CSuplMtlrFsmSession::LocationResp(TInt aReason, const TPositionInfoBase& aPosInfo)
       
   503 	{
       
   504 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::LocationResp() Begin\n");
       
   505 	switch (aReason)
       
   506 		{
       
   507 		case KErrCancel:
       
   508 			// LBS is cancelling the MTLR
       
   509 			CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonNone);
       
   510 			break;
       
   511 					
       
   512 		case KPositionCalculationFutile:
       
   513 			// LBS unable to calculate a position using selected positioning method
       
   514 			CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonFutilePosCalc);
       
   515 			break;
       
   516 			
       
   517 		case KErrNone:
       
   518 			if(EStatePositioningInProgress == iCurrentState)
       
   519 				{
       
   520 				// While a SUPL POS session is in progress, the recipient of the location update is
       
   521 				// the Positioning Protocol state machine.
       
   522 				iPositioningProtocol->LocationResp(aReason, aPosInfo);
       
   523 				}
       
   524 			else if (EStateNetConnectionStarted == iCurrentState)
       
   525 				{
       
   526 				// The position provided by LBS can be sent to 
       
   527 				// the SLP in a SUPL POS INIT. Store it:
       
   528 				TInt err = KErrNone;
       
   529 				TRAP(err, iEventStore->StoreEventL(aPosInfo));
       
   530 
       
   531 				// Leave current state if a connection is already up.
       
   532 				if (IsSessionConnected())
       
   533 						PerformTransition();
       
   534 				}
       
   535 			break;
       
   536 
       
   537 		default:
       
   538 			// Not one of the reason codes for SUPL to handle. If positioning is ongoing
       
   539 			// send the position and the error code to the positioning state machine for
       
   540 			// it to handle according to the specifications of the positioning protocol.
       
   541 			if(EStatePositioningInProgress == iCurrentState)
       
   542 				{
       
   543 				// While a SUPL POS session is in progress, the recipient of the location update is
       
   544 				// the Positioning Protocol state machine.
       
   545 				iPositioningProtocol->LocationResp(aReason, aPosInfo);
       
   546 				}
       
   547 			else
       
   548 				{
       
   549 				// Cancel the MTLR except when this location response arrives after a privacy
       
   550 				// reject (KErrAccessDenied), in which case the cancel must happen after the connection has been 
       
   551 				// created so a SUPL END can be sent
       
   552 				CLbsNetworkProtocolBase::TLbsPrivacyResponse response;
       
   553 				if (!((KErrAccessDenied == aReason) &&
       
   554 					 (iEventStore->GetPrivacyResp(response)) &&
       
   555 					 (CLbsNetworkProtocolBase::EPrivacyResponseRejected == response)))
       
   556 					{
       
   557 					CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonNone);					
       
   558 					}
       
   559 				}
       
   560 				
       
   561 			break;
       
   562 		}
       
   563 
       
   564 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::LocationResp() End\n");
       
   565 	}
       
   566 
       
   567 /** Handle LBS Assistance Data Request
       
   568 
       
   569 The Protocol Manager calls this method following an assitance data request from
       
   570 LBS. However, the PM only does that if a location request had been sent
       
   571 to LBS (which signals the point when the state machines can handle a request
       
   572 for assitance data). Consequently assistance data requests are only handled
       
   573 from states that may have resulted in a Location Request sent to LBS from the
       
   574 state machine. 
       
   575 
       
   576 @param aFilter Assistance data types being requested
       
   577 */
       
   578 void CSuplMtlrFsmSession::AssistanceDataReq(const TLbsAssistanceDataGroup& aFilter)
       
   579 	{
       
   580 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::AssistanceDataReq() Begin\n");
       
   581 	if (EStatePositioningInProgress == iCurrentState)
       
   582 		{
       
   583 		// While a SUPL POS session is in progress, the recipient of the assistance data 
       
   584 		// request is the Positioning Protocol state machine, but only if the assistance
       
   585 		// data request is not empty.
       
   586 		if (aFilter != 0)
       
   587 			{
       
   588 			iPositioningProtocol->AssistanceDataRequest(aFilter);
       
   589 			}
       
   590 		else
       
   591 			{
       
   592 			// ignore assistance data request
       
   593 			// 	
       
   594 			}
       
   595 		}
       
   596 	 else if (EStateNetConnectionStarted == iCurrentState)
       
   597 		{
       
   598 		StoreAssistanceDataRequest(aFilter);
       
   599 		// If the connection had already been created, this state
       
   600 		// was simply waiting for the assistance data. Transition out
       
   601 		// of it.
       
   602 		if (IsSessionConnected())
       
   603 			PerformTransition();		
       
   604 		}
       
   605 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::AssistanceDataReq() End\n");
       
   606 	}
       
   607 
       
   608 
       
   609 //----------------------------- EVENTS FROM POSITIONING PROTOCOL (RRLP) ---------------------------
       
   610 
       
   611 /** Handle a notification of availability of new assistance data from
       
   612 	the Positioning Protocol (RRLP) state machine.
       
   613 */
       
   614 void CSuplMtlrFsmSession::ProcessAssistanceData(const TLbsAsistanceDataGroup& aGroupMask, TInt aReason)
       
   615 	{
       
   616 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::ProcessAssistanceData() Begin\n");
       
   617     ASSERT(iCurrentState == EStatePositioningInProgress);
       
   618 	iObserver.ProcessAssistanceData(aGroupMask, iAssistanceDataBuilderSet, aReason,LocReqType());
       
   619 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::ProcessAssistanceData() End\n");
       
   620 	}
       
   621 
       
   622 /** Handle a Location Request from the Positioning Protocol.
       
   623 @param aQuality  quality parameters for the location request.
       
   624 @param aPosMethod positioning method requested by the Positioning Protocol
       
   625 */
       
   626 void CSuplMtlrFsmSession::ProcessPositioningRequest(const TLbsNetPosRequestQuality& aQuality, const TLbsNetPosRequestMethod& aPosMethod)
       
   627 	{
       
   628 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::ProcessPositioningRequest() Begin\n");
       
   629 	// Disregard this event if MOLR FSM is no longer in positioning state
       
   630 	// (this could happen if the  SUPL session has changed state due to
       
   631 	// a cancel or error but the Positioning Protocol
       
   632 	// state machine has not been notified yet)
       
   633 	if (iCurrentState == EStatePositioningInProgress)
       
   634 		{
       
   635 		// Verify that the positioning method requested by the positioning
       
   636 		// state machine is supported by LBS
       
   637 		TLbsNetPosMethod selectedMethod;//only one to send to LBS
       
   638 		TLbsNetPosCapabilities capabilities;
       
   639 		iObserver.Gateway().GetCapabilities(capabilities);
       
   640 		if (PosMethodSupported(aPosMethod,selectedMethod,capabilities))
       
   641 			{
       
   642 			TLbsNetPosRequestMethod posMethod;
       
   643 			posMethod.SetPosMethods(&selectedMethod, 1);
       
   644 			// SUPL MoLr state machine just passes the request on to Protocol Manager.
       
   645 			iObserver.LocationReq(LbsSessionId(), LocReqType(), aQuality, posMethod);
       
   646 			}
       
   647 		else
       
   648 			{
       
   649 			// The associated positioning protocol has sent a location request
       
   650 			// with an unsupported positioning method. Terminate.
       
   651 			CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonMethodMismatch);	
       
   652 			}
       
   653 		}
       
   654 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::ProcessPositioningRequest() End\n");
       
   655 	}
       
   656 
       
   657 /** Handle a request from the Positioning Protocol state machine to send
       
   658 a positioning protocol message to the network as the payload in a SUPL POS
       
   659 @param aPositioningPayload Positioning Protocol (RRLP) message that will be payload of a SUPL POS message 
       
   660 */
       
   661 void CSuplMtlrFsmSession::PositioningPayloadToNetwork(const CSuplPosPayload* aPositioningPayload)
       
   662 	{
       
   663 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PositioningPayloadToNetwork() Begin\n");
       
   664 
       
   665 	// Disregard this event if MTLR FSM is no longer in positioning state
       
   666 	// (this could happen if the  SUPL session has changed state due to
       
   667 	// a cancel or error but this information the Positioning Protocol
       
   668 	// state machine has not been cancelled yet)
       
   669 	if (iCurrentState == EStatePositioningInProgress)
       
   670 		{
       
   671 		// As this event involves sending a SUPL POS to the network,
       
   672 		// run it through the MTLR state machine
       
   673 		//
       
   674 		StorePosPayload(aPositioningPayload);
       
   675 		// Perform a state transition
       
   676 		PerformTransition();
       
   677 		}
       
   678 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PositioningPayloadToNetwork() End\n");
       
   679 	}
       
   680 
       
   681 /** Handle error notification from Positioning Protocol
       
   682 This is an unrecoverable error. Cancel state machine.
       
   683 @param aError Error code reported by Postioning Protocol State Machine.
       
   684 */
       
   685 void CSuplMtlrFsmSession::PositioningProtocolError(const TInt& aError)
       
   686 	{
       
   687 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PositioningProtocolError() Begin\n");
       
   688 	(void)aError;
       
   689 	ASSERT(iCurrentState == EStatePositioningInProgress);
       
   690 	CancelMachine(ECancelPosProt, EReasonNone);
       
   691 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::PositioningProtocolError() End\n");
       
   692 	}
       
   693 
       
   694 //---------------------------------------------------------------------------------------------------------------------
       
   695 // --------------------------------         STATE CHANGE METHODS          ---------------------------------------------
       
   696 //---------------------------------------------------------------------------------------------------------------------
       
   697 
       
   698 /** Decide next state from EStateSuplInitReceived
       
   699 @return TBool ETrue if the state has changed
       
   700 */
       
   701 TBool CSuplMtlrFsmSession::DetermineStateFromInitReceived()
       
   702 	{
       
   703 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::DetermineStateFromInitReceived() Begin\n");
       
   704 	CLbsNetworkProtocolBase::TLbsPrivacyResponse response;
       
   705 	
       
   706 	// There must be a privacy response in the event store.
       
   707 	// If the privacy response is ignore, then cancel session.
       
   708 	// If the privacy response says accept or reject, then transition
       
   709 	// to the state that connects to the server (EStateNetConnectionStarted).
       
   710 	if (iEventStore->GetPrivacyResp(response))
       
   711 		{
       
   712 		if (CLbsNetworkProtocolBase::EPrivacyResponseIgnored == response)
       
   713 			{
       
   714 			CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonPrivacyIgnored);
       
   715 			}
       
   716 		else
       
   717 			{
       
   718 			iCurrentState = EStateNetConnectionStarted;
       
   719 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromInitReceived() Next state: EStateNetConnectionStarted\n");
       
   720 			}
       
   721 		}
       
   722 	else
       
   723 		{
       
   724 		// A transition out of EStateSuplInitReceived should not have started
       
   725 		// This is only possible if there has been an internal error.
       
   726 		CancelMachine(CSuplFsmSessionBase::ECancelSuplProt, CSuplFsmSessionBase::EReasonNone);
       
   727 		}
       
   728 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::DetermineStateFromInitReceived() End\n");
       
   729 	return ETrue;
       
   730 	}
       
   731 
       
   732 /** Decide next state from EStateNetConnectionStarted
       
   733 @return TBool ETrue if the state has changed
       
   734 @param aForceRedo, indicates that the states entry action must be re-performed when there has been no change in state
       
   735 */
       
   736 TBool CSuplMtlrFsmSession::DetermineStateFromConnectionStarted(TBool& aForceRedo)
       
   737 	{
       
   738 	SUPLLOG(ELogP1, "CSuplMtlrFsmSession::DetermineStateFromConnectionStarted() Begin\n");
       
   739 	// The next state depends on the value of privacy response kept in the event store:
       
   740 	// 1.- If PrivacyReqAccepted: 
       
   741 	//     1.1- Transition to the state EStatePosInitSent if LBS has sent an assistance
       
   742 	//     		data request or a position.
       
   743 	//		or
       
   744 	//
       
   745 	//     1.2- Transition to EStateSuplSessionEnded if the original request in the SUPL INIT
       
   746 	//          was a "no position" one. 
       
   747 	// 2.- If PrivacyReqRejected: no new state selected, just Cancel the session after
       
   748 	//		receiving a "Connected" indication so SUPL END is sent.
       
   749 	
       
   750 	
       
   751 	// Get the preferred method received in a SUPL INIT
       
   752 	// (kept in event store).
       
   753 	TLbsNetPosRequestMethod locReqMethods;
       
   754 	TLbsNetPosMethod prefMethod;
       
   755 	RetrieveInitPosMethod(locReqMethods);
       
   756 	locReqMethods.GetPosMethod(0, prefMethod);
       
   757 	
       
   758 	// always force Entry Actions for this state to be performed on new events,
       
   759 	// even if there is not a change in state.
       
   760 	aForceRedo =  ETrue;
       
   761 	
       
   762 	CLbsNetworkProtocolBase::TLbsPrivacyResponse privResponse;
       
   763 	iEventStore->GetPrivacyResp(privResponse);
       
   764 	if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted == privResponse)
       
   765 		{	
       
   766 		// Only transition to EStatePosInitSent if LBS has sent an Assistance
       
   767 		// Data Request or a Location Response. Otherwise the transition will take place when
       
   768 		// the first of those events occurs after the connection has been created.
       
   769 		if (iEventStore->IsAssistanceDataReqStored() || iEventStore->IsPositionStored())
       
   770 			{
       
   771 			iCurrentState = EStatePosInitSent;
       
   772 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromConnectionStarted() Next state: EStatePosInitSent End\n");
       
   773 			return ETrue;
       
   774 			}
       
   775 		else if (KLbsPositioningMeansNone == prefMethod.PosMeans())	// "no position" in SUPL INIT
       
   776 			{
       
   777 			iCurrentState = EStateSuplSessionEnded;
       
   778 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromConnectionStarted() Next state: EStateSuplSessionEnded End\n");
       
   779 			return ETrue;			
       
   780 			}
       
   781 		else
       
   782 			{
       
   783 			// Nothing to do but wait for new events. Intentionally empty.
       
   784 			}
       
   785 		}
       
   786 	else if((CLbsNetworkProtocolBase::EPrivacyResponseRejected == privResponse) && IsSessionConnected())
       
   787 		{
       
   788 		CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonPrivacyRejected);
       
   789 		SUPLLOG(ELogP1, "CSuplMtlrFsmSession::DetermineStateFromConnectionStarted() CancelMachine End\n");
       
   790 		return ETrue;
       
   791 		}
       
   792 		SUPLLOG(ELogP1, "CSuplMtlrFsmSession::DetermineStateFromConnectionStarted() End\n");
       
   793 		return EFalse;
       
   794 	}