networkprotocolmodules/suplprotocolmodule/SuplProtocol/src/suplmolrfsmsession.cpp
changeset 36 b47902b73a93
parent 0 9cfd9a3ee49c
child 57 3267d9ea3e98
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 MO-LR protocol state machine.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @deprecated
       
    23 */
       
    24 
       
    25 #include "suplmolrfsmsession.h"
       
    26 #include "suplmolrstatehandler.h"
       
    27 #include "suplrrlpstatemachine.h"
       
    28 #include "suplgatewayinterface.h"
       
    29 #include "suplend.h"
       
    30 #include "supldevloggermacros.h"
       
    31 
       
    32 /** KSuplResponseTimerEvent
       
    33 Identity of timer for when SUPL RESPONSE is expected from the network
       
    34 */
       
    35 const TInt KSuplResponseTimerEvent = 0x100;
       
    36 
       
    37 /** KSuplResponseTimerDurationInSec
       
    38 Timer duration for when SUPL RESPONSE is expected from the network
       
    39 */
       
    40 const TInt KSuplResponseTimerDurationInSec = 10;
       
    41 
       
    42 
       
    43 /** KMaxQueueEntry
       
    44 Maximum number of messages waiting to be processed
       
    45 in the state machine event store.
       
    46 */
       
    47 const TInt KMaxQueueEntry = 5;
       
    48 
       
    49 
       
    50 /** Static constructor.
       
    51 @param aObserver Reference to state machine observer.
       
    52 @return A new instance of the CSuplMolrFsmSession class
       
    53 */
       
    54 CSuplMolrFsmSession* CSuplMolrFsmSession::NewL(MSuplFsmSessionObserver& aObserver, TSuplMolrMachineType aMachineType)
       
    55 	{
       
    56 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::NewL() Begin\n");
       
    57 	CSuplMolrFsmSession* self = new (ELeave) CSuplMolrFsmSession(aObserver, aMachineType);
       
    58 	CleanupStack::PushL(self);
       
    59 	self->ConstructL();
       
    60 	CleanupStack::Pop(self);
       
    61 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::NewL() End\n");
       
    62 	return self;
       
    63 	}
       
    64 
       
    65 /** Standard constructor.
       
    66 @param aObserver Reference to state machine observer.
       
    67 */
       
    68 CSuplMolrFsmSession::CSuplMolrFsmSession(MSuplFsmSessionObserver& aObserver, TSuplMolrMachineType aMachineType)
       
    69 :CSuplFsmSessionBase(aObserver)
       
    70 	{
       
    71 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::CSuplMolrFsmSession() Begin\n");
       
    72 	iLocReqType = MLbsNetworkProtocolObserver::EServiceSelfLocation;
       
    73 	iMachineType = aMachineType;
       
    74 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::CSuplMolrFsmSession() End\n");
       
    75 	}
       
    76 
       
    77 
       
    78 /** Standard destructor.
       
    79 */ 
       
    80 CSuplMolrFsmSession::~CSuplMolrFsmSession()
       
    81 	{
       
    82 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::~CSuplMolrFsmSession() Begin\n");
       
    83 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::~CSuplMolrFsmSession() End\n");
       
    84 	}
       
    85 
       
    86 /** Private second-stage constructor.
       
    87 */  
       
    88 void CSuplMolrFsmSession::ConstructL()
       
    89 	{
       
    90 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::ConstructL() Begin\n");
       
    91 	CActiveScheduler::Add(this);
       
    92 
       
    93 	iEventStore = CSuplFsmEventStore::NewL(KMaxQueueEntry);
       
    94 
       
    95 	// Create state handler
       
    96 	iStateHandler = CSuplMoLrStateHandler::NewL(*this);
       
    97 
       
    98 	// Open up assistance data builder
       
    99 	iAssistanceDataBuilderSet.OpenL();
       
   100 
       
   101 	// Create a Positioning Protocol State Machine
       
   102 	iPositioningProtocol = CSuplRrlpFsm::NewL(*this,iAssistanceDataBuilderSet);
       
   103 	
       
   104 	// Create timers used during MO-LR protocol procedure
       
   105 	iSuplProtTimer = CLbsCallbackTimer::NewL(*this);
       
   106 	iSlpSettingsStore = CLbsHostSettingsStore::NewL(KLbsHostSettingsSuplStoreId);
       
   107 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::ConstructL() End\n");
       
   108 	}
       
   109 
       
   110 	
       
   111 /** Retrieve machine type
       
   112 @return TSuplMolrMachineType type of MOLR state machine
       
   113 */
       
   114 CSuplMolrFsmSession::TSuplMolrMachineType CSuplMolrFsmSession::MachineType()
       
   115 	{
       
   116 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::MachineType() Begin\n");
       
   117 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::MachineType() End\n");
       
   118 	return iMachineType;
       
   119 	}
       
   120 	
       
   121 
       
   122 /** GetHostId()
       
   123 This method returns the ID of an entry in the HostSettings store
       
   124 containing the address of the host (SLP) to connect to.
       
   125 For MOLR, if a host in the store has been declared as "default", such
       
   126 host will be used for the MOLR session. Otherwise, the last modified
       
   127 network-provisioned host will be used.
       
   128 If a host is not found in the store using the logic above, then a
       
   129 host is created using the IMSI stored in the SIM (see "Auto
       
   130 configuration of the H-SLP Address" in OMA-AD-SUPL-V1_0-20070615-A, 
       
   131 section 7.2.2).
       
   132 @param aHostId the ID of the host selected for the MOLR
       
   133 @return KErrNone if a valid host ID has been found
       
   134 */
       
   135 TInt CSuplMolrFsmSession::GetHostId(TLbsHostSettingsId& aHostId)
       
   136 	{
       
   137 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::GetHostId() Begin\n");
       
   138 	TInt err = KErrNotFound;
       
   139 	TBool hostFound = EFalse;
       
   140 	if (iSlpSettingsStore)
       
   141 		{
       
   142 		TLbsHostSettingsSupl slpSettings;
       
   143 		TLbsHostSettingsId 	settingsId;
       
   144 		// Get the default SLP if one exists
       
   145 		err = iSlpSettingsStore->GetDefaultHostSettings(slpSettings, settingsId);
       
   146 		if (KErrNone == err)
       
   147 			{
       
   148 			aHostId = settingsId;
       
   149 			hostFound = ETrue;
       
   150 			}
       
   151 		else
       
   152 			{
       
   153 			// If no default SLP is present, get the
       
   154 			// network-provisioned SLP that has been 
       
   155 			// modified most recently
       
   156 			TTime mostRecent = 0;
       
   157 			err = iSlpSettingsStore->RewindHostSettings();
       
   158 			if (KErrNone == err)
       
   159 				{
       
   160 				while (KErrNone == err)
       
   161 					{
       
   162 					err = iSlpSettingsStore->GetNextHostSettingsByCreator(KLbsHostSettingsDevProvCreatorId, slpSettings, settingsId);		
       
   163 					if (KErrNone == err)
       
   164 						{
       
   165 						if (mostRecent < slpSettings.LastModified())
       
   166 							{
       
   167 							mostRecent = slpSettings.LastModified();
       
   168 							aHostId = settingsId;
       
   169 							hostFound = ETrue;
       
   170 							}
       
   171 						}
       
   172 					}
       
   173 				}			
       
   174 			}
       
   175 	}	
       
   176 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::GetHostId() End\n");
       
   177 	if(!hostFound)
       
   178 		{
       
   179 		return GenerateHostId(aHostId);
       
   180 		}
       
   181 	
       
   182 	return KErrNone;
       
   183 	}
       
   184 
       
   185 /** Start SUPL RESPONSE timer
       
   186 The state handler calls this when it has issued a SUPL START
       
   187 to the network and it requires a response before the timer expires.
       
   188 */
       
   189 void CSuplMolrFsmSession::StartSuplResponseTimer()
       
   190 	{
       
   191 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::StartSuplResponseTimer() Begin\n");
       
   192 	iSuplProtTimer->EventAfter(TTimeIntervalSeconds(KSuplResponseTimerDurationInSec), KSuplResponseTimerEvent);
       
   193 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::StartSuplResponseTimer() End\n");
       
   194 	}
       
   195 
       
   196 /** Initialise internal state attributes.
       
   197 This is used when new MO-LR procedure commences.
       
   198 */
       
   199 void CSuplMolrFsmSession::InitialiseProcedure()
       
   200 	{
       
   201 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::InitialiseProcedure() Begin\n");
       
   202 	// Initialise state machine
       
   203 	InitialiseMachineBase();
       
   204 	iCurrentState = EStateProcedureNull;
       
   205 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::InitialiseProcedure() End\n");
       
   206 	}
       
   207 	
       
   208 
       
   209 /** State transition.
       
   210 This method determines the next state to be adopted by the state machine.
       
   211 @return TBool ETrue if the state has changed.
       
   212 @param aForceRedo, indicates that the states entry action must be re-performed when there has been no change in state
       
   213 */
       
   214 TBool CSuplMolrFsmSession::SelectNextState(TBool& aForceRedo)
       
   215 	{
       
   216 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Begin\n");
       
   217 	TBool stateChanged = ETrue;
       
   218 	aForceRedo = EFalse;
       
   219 	
       
   220 	// Regardless of current state, check first if an event has occurred
       
   221 	// that implies cancelling the machine (terminate session)
       
   222 	if (IsCancelPending())
       
   223 		{
       
   224 		SetMachineAsCancelling();
       
   225 		iCurrentState = (IsSessionConnected() && iSessionInProgress)? EStateSuplSessionEnded : EStatePosSessionEnded;
       
   226 		}
       
   227 	else
       
   228 		{
       
   229 		// Set new state	
       
   230 		switch (iCurrentState)
       
   231 			{
       
   232 			
       
   233 		case EStateProcedureNull:
       
   234 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateProcedureNull\n");
       
   235 			iCurrentState = EStateNetConnectionStarted;
       
   236 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateNetConnectionStarted\n");
       
   237 			break;
       
   238 			
       
   239 		case EStateNetConnectionStarted:
       
   240 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateNetConnectionStarted\n");
       
   241 			iCurrentState = EStateStartSent;
       
   242 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateStartSent\n");
       
   243 			break;
       
   244 			
       
   245 		case EStateStartSent:
       
   246 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateStartSent\n");
       
   247 			stateChanged = DetermineStateFromStartSent();
       
   248 			break;
       
   249 			
       
   250 		case EStateResponseReceived:
       
   251 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateResponseReceived\n");
       
   252 		    iCurrentState = EStatePosInitSent;
       
   253 		    SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosInitSent\n");
       
   254 			break;
       
   255 			
       
   256 		case EStatePosInitSent:
       
   257 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePosInitSent\n");
       
   258 			stateChanged = DetermineStateFromPosInitSent();
       
   259 			break;
       
   260 
       
   261 		case EStatePositioningInProgress:
       
   262 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePositioningInProgress\n");
       
   263 			stateChanged = DetermineStateFromPositioningInProgress(aForceRedo);
       
   264 			break;
       
   265 
       
   266 		case EStatePositionReceived:
       
   267 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePositionReceived\n");
       
   268 			iCurrentState = EStatePosSessionEnded;
       
   269 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosSessionEnded\n");
       
   270 			SetMachineAsNotCancellable();
       
   271 			break;
       
   272 			
       
   273 		case EStateSuplSessionEnded:
       
   274 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateSuplSessionEnded\n");
       
   275 			iCurrentState = EStatePosSessionEnded;
       
   276 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosSessionEnded\n");
       
   277 			break;
       
   278 
       
   279 		case EStatePosSessionEnded:
       
   280 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePosSessionEnded\n");
       
   281 			iCurrentState = EStateLbsSessionEnded;
       
   282 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateLbsSessionEnded\n");
       
   283 			break;
       
   284 			
       
   285 		case EStateLbsSessionEnded:
       
   286 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateLbsSessionEnded\n");
       
   287 			iCurrentState = EStateNetConnectionClosed;
       
   288 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateNetConnectionClosed\n");
       
   289 			break;
       
   290 			
       
   291 		case EStateNetConnectionClosed:
       
   292 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateNetConnectionClosed\n");
       
   293 			// Procedure has completed
       
   294 			iCurrentState = EStateProcedureNull;
       
   295 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateProcedureNull\n");
       
   296 			break;
       
   297 			
       
   298 		default:
       
   299 			SUPLLOG(ELogP3, "CSuplMolrFsmSession::SelectNextState() unknown entry state\n");
       
   300 			ASSERT(EFalse);
       
   301 			break;
       
   302 			};
       
   303 		}
       
   304 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() End\n");
       
   305 	return stateChanged;
       
   306 	}
       
   307 	
       
   308 
       
   309 /** Complete the procedure.
       
   310 */  
       
   311 void CSuplMolrFsmSession::CompleteProcedure()
       
   312 	{
       
   313 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::CompleteProcedure() Begin\n");
       
   314 	// Complete state machine
       
   315 	CompleteMachineBase();
       
   316 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::CompleteProcedure() End\n");
       
   317 	}
       
   318 	
       
   319 /** Complete a state transition.
       
   320 This is called by the base class when a state transition has
       
   321 concluded and it provides an opportunity for the state machine 
       
   322 to perform actions required immediately after this transition.
       
   323 
       
   324 The method can also initiate a further change of state. This is
       
   325 relevant when the state machine is required to perform an autonomous
       
   326 transition from one state to another e.g. this occurs when several
       
   327 interactions are required arising from a single external trigger.
       
   328 */
       
   329 void CSuplMolrFsmSession::PostTransition()
       
   330 	{
       
   331 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::PostTransition() Begin\n");
       
   332 	// Some states are transitory i.e. they require
       
   333 	// an automatic transition to the next state
       
   334 	if (IsCancelPending() ||
       
   335 	    ((EStateResponseReceived == iCurrentState) && (ESuplMolrCellBased == MachineType())) || 
       
   336 		EStatePositionReceived		== iCurrentState ||
       
   337 	 	EStateSuplSessionEnded		== iCurrentState ||
       
   338 	 	EStatePosSessionEnded		== iCurrentState ||
       
   339 	 	EStateLbsSessionEnded		== iCurrentState ||
       
   340 	 	EStateNetConnectionClosed	== iCurrentState)
       
   341 		{
       
   342 		// Perform a state transition
       
   343 		PerformTransition();
       
   344 		}
       
   345 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::PostTransition() End\n");
       
   346 	}
       
   347 
       
   348 
       
   349 /** Cancel the active procedure
       
   350 */  
       
   351 void CSuplMolrFsmSession::CancelProcedure()
       
   352 	{
       
   353 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::CancelProcedure() Begin\n");
       
   354 	// Kill all timers
       
   355 	iSuplProtTimer->Cancel();
       
   356 
       
   357 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::CancelProcedure() End\n");
       
   358 	}
       
   359 
       
   360 
       
   361 /** Timer expired callback.
       
   362 This is called by a CStateTimer object when the timer
       
   363 has expired - the event is identified by aEvent parameter.
       
   364 @param aTimerId The timer event identifier.
       
   365 */
       
   366 void CSuplMolrFsmSession::OnTimerEventL(TInt aTimerId)
       
   367 	{
       
   368 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::OnTimerEventL() Begin\n");
       
   369 	// Perform relevant action for the expired timer
       
   370 	switch (aTimerId)
       
   371 		{
       
   372 	// Connection result timer
       
   373 	case KSessionConnectedTimerEvent:
       
   374 		CancelMachine(CSuplFsmSessionBase::ECancelNetwork,CSuplFsmSessionBase::EReasonTimerExpiry);
       
   375 		break;
       
   376 
       
   377 	// SUPL RESPONSE timer
       
   378 	case KSuplResponseTimerEvent:
       
   379 		CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonTimerExpiry);
       
   380 		break;
       
   381 
       
   382 	// SUPL POS timer
       
   383 	case KSuplPosTimerEvent:
       
   384 		CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonTimerExpiry);
       
   385 		break;
       
   386 
       
   387 	case KSuplEndTimerEvent:
       
   388 		CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonTimerExpiry);
       
   389 		break;
       
   390 		
       
   391 	// Ignore unknown timer events
       
   392 	default:
       
   393 		break;
       
   394 		};
       
   395 
       
   396 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::OnTimerEventL() End\n");
       
   397 	}
       
   398 
       
   399 
       
   400 //---------------------------------------------------------------------------------------------------------------------
       
   401 // --------------------------------         EVENT HANDLING METHODS          -------------------------------------------
       
   402 //---------------------------------------------------------------------------------------------------------------------
       
   403 
       
   404 
       
   405 //----------------------------- EVENTS FROM PROTOCOL MANAGER (LBS) --------------------------						
       
   406 
       
   407 /** Handle LBS request for MO-LR
       
   408 @param aSessionId The session ID supplied by LBS.
       
   409 */
       
   410 void CSuplMolrFsmSession::MoLrReq(const TLbsNetSessionId& aSessionId, const TLbsNetPosRequestOptionsBase& aOptions)
       
   411 	{
       
   412 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::MoLrReq() Begin\n");
       
   413 
       
   414 	// Initialise the new procedure
       
   415 	InitialiseProcedure();
       
   416 	
       
   417 	// Store the supplied ID information
       
   418 	SetSessionId(aSessionId);
       
   419 
       
   420 	// Store MOLR Options needed for SUPL START
       
   421 	//
       
   422 	if (KErrNone != StoreLocationRequest(aOptions))
       
   423 		CancelMachine(CSuplFsmSessionBase::ECancelClosing, CSuplFsmSessionBase::EReasonNone);
       
   424 
       
   425 	// Perform a state transition
       
   426 	PerformTransition();
       
   427 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::MoLrReq() End\n");
       
   428 	}
       
   429 
       
   430 
       
   431 /** Handle LBS Location response
       
   432 @param aReason Location response error reason.
       
   433 @param aPosInfo The location information response from LBS.
       
   434 */
       
   435 void CSuplMolrFsmSession::LocationResp(TInt aReason, const TPositionInfoBase& aPosInfo)
       
   436 	{
       
   437 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::LocationResp() Begin\n");
       
   438 	switch (aReason)
       
   439 		{
       
   440 		case KErrNone:
       
   441 			if(EStatePositioningInProgress == iCurrentState)
       
   442 				{
       
   443 				// While a SUPL POS session is in progress, the recipient of the location update is
       
   444 				// the Positioning Protocol state machine.
       
   445 				iPositioningProtocol->LocationResp(aReason, aPosInfo);
       
   446 				}
       
   447 			else
       
   448 				{
       
   449 				// SUPL state machine has no use for a location update. Ignore it.
       
   450 				}
       
   451 			break;
       
   452 			
       
   453 		case KPositionCalculationFutile:
       
   454 			// LBS unable to calculate a position using selected positioning method
       
   455 			CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonFutilePosCalc);
       
   456 			break;
       
   457 
       
   458 		default:
       
   459 			if(EStatePositioningInProgress == iCurrentState)
       
   460 				{
       
   461 				// Send the position and the error code to the positioning state machine for
       
   462 				// it to handle according to the specifications of the Positioning Protocol.
       
   463 				iPositioningProtocol->LocationResp(aReason, aPosInfo);
       
   464 				}
       
   465 			else
       
   466 				{
       
   467 				CancelMachine(ECancelSuplProt,EReasonNone);
       
   468 				}
       
   469 			break;
       
   470 		}
       
   471 			
       
   472 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::LocationResp() End\n");
       
   473 	}
       
   474 
       
   475 /** Handle LBS Assistance Data Request
       
   476 
       
   477 The Protocol Manager calls this method following an assitance data request from
       
   478 LBS. However, the PM only does that if a location request had been sent
       
   479 to LBS (which signals the point when the state machines can handle a request
       
   480 for assitance data). Consequently assistance data requests are only handled
       
   481 from states that may have resulted in a Location Request sent to LBS from the
       
   482 state machine. 
       
   483 
       
   484 @param aFilter Assistance data types being requested
       
   485 */
       
   486 void CSuplMolrFsmSession::AssistanceDataReq(const TLbsAssistanceDataGroup& aFilter)
       
   487 	{
       
   488 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::AssistanceDataReq() Begin\n");
       
   489 	if (iCurrentState == EStatePositioningInProgress)
       
   490 		{
       
   491 		// While a SUPL POS session is in progress, the recipient of the assistance data 
       
   492 		// request is the Positioning Protocol state machine, but only if the assistance
       
   493 		// data request is not empty.
       
   494 		if (aFilter != 0)
       
   495 			{
       
   496 			iPositioningProtocol->AssistanceDataRequest(aFilter);
       
   497 			}
       
   498 		else
       
   499 			{
       
   500 			// ignore assistance data request
       
   501 			// 	
       
   502 			}
       
   503 		}
       
   504 	else if (iCurrentState == EStateResponseReceived)
       
   505 		{
       
   506 		// The assistance data request can be sent to the SLP in a SUPL POS INIT
       
   507 		StoreAssistanceDataRequest(aFilter);
       
   508 		PerformTransition();
       
   509 		}
       
   510 	 else
       
   511 		{
       
   512 		 // Assistance data request has arrived unsolicitedly from LBS and SUPL has no 
       
   513 		 // use for it. Log it and ignore it.
       
   514 		}	
       
   515 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::AssistanceDataReq() End\n");
       
   516 	}
       
   517 
       
   518 
       
   519 /** Handle a request to switch LBS session Id
       
   520 
       
   521 The Protocol Manager calls this method following a conflict whose resolution
       
   522 requires that the MOLR procedure remains active but the session ID changes
       
   523 when a message is sent to LBS (the session ID in SUPL messages must remain the
       
   524 same)
       
   525 
       
   526 
       
   527 @param aFilter Assistance data types being requested
       
   528 */
       
   529 void CSuplMolrFsmSession::AdoptNewLbsSessionId(const TLbsNetSessionId& aSessionId)
       
   530 {
       
   531 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::AdoptNewLbsSessionId() Begin\n");
       
   532 	iSessionIdReplaced = ETrue;
       
   533 	iReplacementSessionId = aSessionId;
       
   534 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::AdoptNewLbsSessionId() End\n");	
       
   535 }
       
   536 
       
   537 
       
   538 //----------------------------- EVENTS FROM POSITIONING PROTOCOL (RRLP) ---------------------------
       
   539 
       
   540 /** Handle a notification of availability of new assistance data from
       
   541 	the Positioning Protocol (RRLP) state machine.
       
   542 */
       
   543 void CSuplMolrFsmSession::ProcessAssistanceData(const TLbsAsistanceDataGroup& aGroupMask, TInt aReason)
       
   544 	{
       
   545 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessAssistanceData() Begin\n");
       
   546     ASSERT(iCurrentState == EStatePositioningInProgress);
       
   547 	iObserver.ProcessAssistanceData(aGroupMask, iAssistanceDataBuilderSet, aReason,LocReqType());
       
   548 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessAssistanceData() End\n");
       
   549 	}
       
   550 
       
   551 /** Handle a Location Request from the Positioning Protocol.
       
   552 @param aQuality  quality parameters for the location request.
       
   553 @param aPosMethod positioning method requested by the Positioning Protocol
       
   554 */
       
   555 void CSuplMolrFsmSession::ProcessPositioningRequest(const TLbsNetPosRequestQuality& aQuality, const TLbsNetPosRequestMethod& aPosMethod)
       
   556 	{
       
   557 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessPositioningRequest() Begin\n");
       
   558 	// Disregard this event if MOLR FSM is no longer in positioning state
       
   559 	// (this could happen if the  SUPL session has changed state due to
       
   560 	// a cancel or error but the Positioning Protocol
       
   561 	// state machine has not been notified yet)
       
   562 	if (iCurrentState == EStatePositioningInProgress)
       
   563 		{
       
   564 		// Verify that the positioning method requested by the positioning
       
   565 		// state machine is supported by LBS
       
   566 		TLbsNetPosMethod selectedMethod;//only one to send to LBS
       
   567 		TLbsNetPosCapabilities capabilities;
       
   568 		iObserver.Gateway().GetCapabilities(capabilities);
       
   569 		if (PosMethodSupported(aPosMethod,selectedMethod,capabilities))
       
   570 			{
       
   571 			TLbsNetPosRequestMethod posMethod;
       
   572 			posMethod.SetPosMethods(&selectedMethod, 1);
       
   573 			// SUPL MoLr state machine just passes the request on to Protocol Manager.
       
   574 			iObserver.LocationReq(LbsSessionId(), LocReqType(), aQuality, posMethod);
       
   575 			}
       
   576 		else
       
   577 			{
       
   578 			// The associated positioning protocol has sent a location request
       
   579 			// with an unsupported positioning method. Terminate.
       
   580 			CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonMethodMismatch);	
       
   581 			}
       
   582 		}
       
   583 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessPositioningRequest() End\n");
       
   584 	}
       
   585 
       
   586 /** Handle a request from the Positioning Protocol state machine to send
       
   587 a positioning protocol message to the network as the payload in a SUPL POS
       
   588 @param aPositioningPayload Positioning Protocol (RRLP) message that will be payload of a SUPL POS message 
       
   589 */
       
   590 void CSuplMolrFsmSession::PositioningPayloadToNetwork(const CSuplPosPayload* aPositioningPayload)
       
   591 	{
       
   592 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningPayloadToNetwork() Begin\n");
       
   593 
       
   594 	// Disregard this event if MOLR FSM is no longer in positioning state
       
   595 	// (this could happen if the  SUPL session has changed state due to
       
   596 	// a cancel or error but this information the Positioning Protocol
       
   597 	// state machine has not been cancelled yet)
       
   598 	if (iCurrentState == EStatePositioningInProgress)
       
   599 		{
       
   600 		// As this event involves sending a SUPL POS to the network,
       
   601 		// run it through the MOLR state machine
       
   602 		//
       
   603 		StorePosPayload(aPositioningPayload);
       
   604 		// Perform a state transition
       
   605 		PerformTransition();
       
   606 		}
       
   607 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningPayloadToNetwork() End\n");
       
   608 	}
       
   609 
       
   610 /** Handle error notification from Positioning Protocol
       
   611 This is an unrecoverable error. Cancel state machine.
       
   612 @param aError Error code reported by Postioning Protocol State Machine.
       
   613 */
       
   614 void CSuplMolrFsmSession::PositioningProtocolError(const TInt& aError)
       
   615 	{
       
   616 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningProtocolError() Begin\n");
       
   617 	(void)aError;
       
   618 	ASSERT(iCurrentState == EStatePositioningInProgress);
       
   619 	CancelMachine(CSuplFsmSessionBase::ECancelPosProt, CSuplFsmSessionBase::EReasonNone);
       
   620 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningProtocolError() End\n");
       
   621 	}
       
   622 
       
   623 
       
   624 //---------------------------------------------------------------------------------------------------------------------
       
   625 // --------------------------------         STATE CHANGE METHODS          ---------------------------------------------
       
   626 //---------------------------------------------------------------------------------------------------------------------
       
   627 
       
   628 /** Decide next state from EStateStartSent
       
   629 @return TBool ETrue if the state has changed
       
   630 */
       
   631 TBool CSuplMolrFsmSession::DetermineStateFromStartSent()
       
   632 	{
       
   633 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent() Begin\n");
       
   634 	TBool stateChanged = ETrue;
       
   635 	
       
   636 	// Check what SUPL Message was received.
       
   637 	//
       
   638 	const CSuplMessageBase* msg = NULL;
       
   639 	TBool messageAvailable = iEventStore->IsSuplMessageStored(msg);
       
   640 
       
   641 	if (messageAvailable)
       
   642 		{
       
   643 		// Received message was stored as constant (read-only) but
       
   644 		// access to non-constant methods is needed
       
   645 		CSuplMessageBase* message = const_cast<CSuplMessageBase*> (msg);
       
   646 		if (CSuplMessageBase::ESuplEnd == message->MessageType())
       
   647 			{
       
   648 			iSessionInProgress = EFalse;
       
   649 			CSuplEnd* suplEnd = static_cast <CSuplEnd*> (message);
       
   650 
       
   651 			if (suplEnd->PositionPresent())
       
   652 				{
       
   653 				iCurrentState = EStatePositionReceived;
       
   654 				SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent(). Next state : EStatePositionReceived\n");
       
   655 				// The position is about to be sent to LBS.
       
   656 				// The states following will terminate the session.
       
   657 				// Handling a cancel would result in sending an 
       
   658 				// unnecessary SUPL END to the SLP.
       
   659 				SetMachineAsNotCancellable();
       
   660 				}
       
   661 			else
       
   662 				{
       
   663 				// Unexpected session termination.
       
   664 				// Remember this fact before switching state.
       
   665 				iEventStore->SetUnexpectedSuplEnd();
       
   666 				iCurrentState = EStateLbsSessionEnded;
       
   667 				SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent(). Next state : EStateLbsSessionEnded\n");
       
   668 				SetMachineAsNotCancellable();
       
   669 				}
       
   670 			}
       
   671 		else if (CSuplMessageBase::ESuplResponse == message->MessageType())
       
   672 			{
       
   673 			iCurrentState = EStateResponseReceived;
       
   674 			SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent(). Next state : EStateResponseReceived\n");
       
   675 			}
       
   676 		else
       
   677 			{
       
   678 			// Unexpected SUPL Message was received
       
   679 			//
       
   680 			CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonUnexpectedMessage);
       
   681 			}
       
   682 		}
       
   683 	else
       
   684 		{
       
   685 		stateChanged = EFalse;
       
   686 		}
       
   687 	SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent() End\n");
       
   688 	return stateChanged;
       
   689 	}