networkprotocolmodules/networkprotocolmodule/LbsProtocolModule/src/cx3pstatemachine.cpp
changeset 0 9cfd9a3ee49c
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     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 // This file provides the implementation of the class for
       
    15 // the X3P protocol state machine.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @released
       
    23 */
       
    24 
       
    25 #include "cx3pstatemachine.h"
       
    26 #include "cx3pstatehandler.h"
       
    27 
       
    28 
       
    29 /** KX3pReqIssuedTimerEvent
       
    30 Identity of timer for when X3P request issued to network
       
    31 */
       
    32 const TInt KX3pReqIssuedTimerEvent = 0x1000;
       
    33 
       
    34 /** KX3pReqIssuedTimerDurationInSec
       
    35 Timer duration for when X3P request issued to network
       
    36 */
       
    37 const TInt KX3pReqIssuedTimerDurationInSec = 20;
       
    38 
       
    39 /** KLocRespTimerEvent
       
    40 Identity of timer for when location response expected by network
       
    41 */
       
    42 const TInt KLocRespTimerEvent = 0x2000;
       
    43 
       
    44 /** KLocRespTimerDurationInSec
       
    45 Timer duration for when location response expected by network
       
    46 */
       
    47 const TInt KLocRespTimerDurationInSec = 64;
       
    48 
       
    49 /** KX3pFacResultTimerEvent
       
    50 Identity of timer for when facility result expected from network
       
    51 */
       
    52 const TInt KX3pFacResultTimerEvent = 0x300;
       
    53 
       
    54 /** KX3pFacResultTimerDurationInSec
       
    55 Timer duration for when facility result expected from network
       
    56 */
       
    57 const TInt KX3pFacResultTimerDurationInSec = 10;
       
    58 
       
    59 /** KMaxQueueEntry
       
    60 Maximum entries in this state machine request queue.
       
    61 */
       
    62 const TInt KMaxQueueEntry = 5;
       
    63 
       
    64 
       
    65 /** Static constructor.
       
    66 @param aObserver Reference to state machine observer.
       
    67 @return A new instance of the CX3pStateMachine class
       
    68 */  
       
    69 CX3pStateMachine* CX3pStateMachine::NewL(MStateMachineObserver& aObserver)
       
    70 	{
       
    71 	CX3pStateMachine* self = new (ELeave) CX3pStateMachine(aObserver);
       
    72 	CleanupStack::PushL(self);
       
    73 	self->ConstructL();
       
    74 	CleanupStack::Pop(self);
       
    75 	return self;
       
    76 	}
       
    77 
       
    78 
       
    79 /** Standard constructor.
       
    80 @param aObserver Reference to state machine observer.
       
    81 */  
       
    82 CX3pStateMachine::CX3pStateMachine(MStateMachineObserver& aObserver)
       
    83 : CStateMachineBase(aObserver)
       
    84 	{
       
    85 	iLocReqType = MLbsNetworkProtocolObserver::EServiceTransmitThirdParty;
       
    86 	}
       
    87 
       
    88 
       
    89 /** Standard destructor.
       
    90 */  
       
    91 CX3pStateMachine::~CX3pStateMachine()
       
    92 	{
       
    93 	delete iLocRespTimer;
       
    94 	delete iX3pReqIssuedTimer;
       
    95 	delete iFacResultTimer;
       
    96 	}
       
    97 
       
    98 
       
    99 /** Private second-stage constructor.
       
   100 */  
       
   101 void CX3pStateMachine::ConstructL()
       
   102 	{
       
   103 	CActiveScheduler::Add(this);
       
   104 
       
   105 	// Create state handler
       
   106 	iStateHandler = CX3pStateHandler::NewL(*this);
       
   107 
       
   108 	// Create timers used during X3P protocol procedure
       
   109 	iX3pReqIssuedTimer = CLbsCallbackTimer::NewL(*this);
       
   110 	iLocRespTimer = CLbsCallbackTimer::NewL(*this);
       
   111 	iFacResultTimer = CLbsCallbackTimer::NewL(*this);
       
   112 	iAssistDataTimer = CLbsCallbackTimer::NewL(*this);
       
   113 
       
   114 
       
   115 	// Create request queue
       
   116 	iQueue = CStateQueue::NewL(KMaxQueueEntry);
       
   117 
       
   118 	// We are not cancelling
       
   119 	iStillCancelling = EFalse;
       
   120 	}
       
   121 
       
   122 
       
   123 /** Retrieve current X3P state
       
   124 @return TX3pState Current X3P state
       
   125 */
       
   126 CX3pStateMachine::TX3pState CX3pStateMachine::CurrentState()
       
   127 	{
       
   128 	return iCurrentState;
       
   129 	}
       
   130 
       
   131 	
       
   132 /** Start X3P request timer
       
   133 The state handler calls this when it has issued an X3P request
       
   134 to the network and it requires a response before the timer expires.
       
   135 */
       
   136 void CX3pStateMachine::StartX3pReqTimer()
       
   137 	{
       
   138 	if(iX3pReqIssuedTimer->IsActive())
       
   139 		{
       
   140 		iX3pReqIssuedTimer->Cancel();
       
   141 		}
       
   142 	iX3pReqIssuedTimer->EventAfter(TTimeIntervalSeconds(KX3pReqIssuedTimerDurationInSec), KX3pReqIssuedTimerEvent);
       
   143 	}
       
   144 
       
   145 	
       
   146 /** Start location response timer
       
   147 The state handler calls this when it has sent a location request
       
   148 to the client and requires a response before the timer expires.
       
   149 */
       
   150 void CX3pStateMachine::StartLocRespTimer()
       
   151 	{
       
   152 	if(iLocRespTimer->IsActive())
       
   153 		{
       
   154 		iLocRespTimer->Cancel();
       
   155 		}
       
   156 	iLocRespTimer->EventAfter(TTimeIntervalSeconds(KLocRespTimerDurationInSec), KLocRespTimerEvent);
       
   157 	}
       
   158 
       
   159 
       
   160 /** Start facility result timer
       
   161 The state handler calls this when it has sent a location report
       
   162 to the network and requires a result before the timer expires.
       
   163 */
       
   164 void CX3pStateMachine::StartFacResultTimer()
       
   165 	{
       
   166 	if(iFacResultTimer->IsActive())
       
   167 		{
       
   168 		iFacResultTimer->Cancel();
       
   169 		}
       
   170 	iFacResultTimer->EventAfter(TTimeIntervalSeconds(KX3pFacResultTimerDurationInSec), KX3pFacResultTimerEvent);
       
   171 	}
       
   172 	
       
   173 /** Response sent
       
   174 Remember that a Measurement Response Location was sent to the network
       
   175 */
       
   176 void CX3pStateMachine::ResponseSent()
       
   177 	{
       
   178 	iIsLocRespSent = ETrue;
       
   179 	}
       
   180 
       
   181 /** Network Result Location.
       
   182 This is called by state handlers to retrieve the most
       
   183 recent reported network result location.
       
   184 @return TPositionInfoBase Currently held network result position
       
   185 */
       
   186 const TPositionInfoBase& CX3pStateMachine::NetResultLoc() const
       
   187 	{
       
   188 	return iNetResultPosInfo;
       
   189 	}
       
   190 
       
   191 
       
   192 /** Store network resulting location
       
   193 @param aPosInfo Network result location information
       
   194 */
       
   195 void CX3pStateMachine::StoreNetResultLoc(const TPositionInfoBase& aPosInfo)
       
   196 	{
       
   197 	iNetResultPosInfo = reinterpret_cast <const TPositionInfo&> (aPosInfo);
       
   198 	}
       
   199 
       
   200 /** Retrieve the transmit destination
       
   201 @return const TDesC& A reference to the transmit destination.
       
   202 */
       
   203 const TDesC& CX3pStateMachine::Destination() const
       
   204 	{
       
   205 	return iDestination;
       
   206 	}
       
   207 
       
   208 
       
   209 /** Store the requested transmit destination
       
   210 @param aDest The destination for this transmit request
       
   211 */
       
   212 void CX3pStateMachine::StoreDestination(const TDesC& aDest)
       
   213 	{
       
   214 	// Check size of destination string
       
   215 	if (KMaxSizeX3pDestination < aDest.Length())
       
   216 		{
       
   217 		User::Panic(KProtocolModulePanic, EProtocolModuleX3PDestination);
       
   218 		}
       
   219 	// Store destination
       
   220 	iDestination = aDest;
       
   221 	}
       
   222 
       
   223 
       
   224 /** Store the queued transmit destination
       
   225 @param aDest The destination for a queued transmit request
       
   226 */
       
   227 void CX3pStateMachine::QueueDestination(const TDesC& aDest)
       
   228 	{
       
   229 	// Check size of destination string
       
   230 	if (KMaxSizeX3pDestination < aDest.Length())
       
   231 		{
       
   232 		User::Panic(KProtocolModulePanic, EProtocolModuleX3PDestination);
       
   233 		}
       
   234 	// Store destination
       
   235 	iQueueDestination = aDest;
       
   236 	}
       
   237 
       
   238 
       
   239 /** Initialise internal state attributes.
       
   240 This is used when new X3P procedure commences.
       
   241 */
       
   242 void CX3pStateMachine::InitialiseProcedure()
       
   243 	{
       
   244 	// Initialise state machine
       
   245 	InitialiseMachineBase();
       
   246 
       
   247 	ASSERT(iStateHandler != NULL);
       
   248 	iStateHandler->Initialise();
       
   249 	}
       
   250 	
       
   251 
       
   252 /** Prepare state transition.
       
   253 */  
       
   254 void CX3pStateMachine::PreStateTransition()
       
   255 	{
       
   256 	}
       
   257 	
       
   258 
       
   259 /** State transition.
       
   260 This method determines the next state to be adopted by the state machine.
       
   261 */  
       
   262 void CX3pStateMachine::StateTransition()
       
   263 	{
       
   264 	if (CancelPending())
       
   265 		{
       
   266 		SetMachineAsCancelling();
       
   267 		iCurrentState = EStateCancelling;
       
   268 		}
       
   269 	else
       
   270 		{
       
   271 		// Set new state		
       
   272 		switch (iCurrentState)
       
   273 			{
       
   274 			
       
   275 		case EStateNull:
       
   276 			iCurrentState = EStateClientReqRecvd;
       
   277 			break;
       
   278 			
       
   279 		case EStateClientReqRecvd:
       
   280 			iCurrentState = EStateNetSessStarted;
       
   281 			break;
       
   282 			
       
   283 		case EStateNetSessStarted:
       
   284 			iCurrentState = EStateMeasureDataRecvd;
       
   285 			break;
       
   286 			
       
   287 		case EStateMeasureDataRecvd:
       
   288 			iCurrentState = EStateNetBasedLocSent;
       
   289 			break;
       
   290 			
       
   291 		case EStateNetBasedLocSent:
       
   292 			iIsMeasureControlHandled = ETrue;
       
   293 			iCurrentState = EStateLocReqByNet;
       
   294 			break;
       
   295 			
       
   296 		case EStateLocReqByNet:
       
   297 			iCurrentState = EStateLocRespRecvd;
       
   298 			break;
       
   299 			
       
   300 		case EStateLocRespRecvd:
       
   301 			iCurrentState = EStateLocSentToNet;
       
   302 			break;
       
   303 			
       
   304 		case EStateLocSentToNet:
       
   305 			iCurrentState = EStateNetSessToClose;
       
   306 			break;
       
   307 			
       
   308 		case EStateNetSessToClose:
       
   309 			// If a network result is provided then it is sent to LBS
       
   310 			// otherwise the LBS client session closes
       
   311 			iCurrentState = iIsNetResultLocAvailable ? EStateNetResultSent : EStateClientSessToClose;
       
   312 			break;
       
   313 			
       
   314 		case EStateNetResultSent:
       
   315 			iCurrentState = EStateClientSessToClose;
       
   316 			break;
       
   317 				
       
   318 		case EStateClientSessToClose:
       
   319 			iCurrentState = EStateSessionsClosed;
       
   320 			break;
       
   321 			
       
   322 		case EStateSessionsClosed:
       
   323 			// Procedure has completed
       
   324 			CompleteProcedure();
       
   325 			break;
       
   326 			
       
   327 		case EStateCancelling:
       
   328 			iCurrentState = EStateNetSessToClose;
       
   329 			break;
       
   330 
       
   331 		default:
       
   332 			User::Panic(KProtocolModulePanic, EProtocolModuleX3pState);
       
   333 			break;
       
   334 			};
       
   335 		}
       
   336 
       
   337 	}
       
   338 	
       
   339 
       
   340 /** Complete the procedure.
       
   341 */  
       
   342 void CX3pStateMachine::CompleteProcedure()
       
   343 	{
       
   344 	iCurrentState = EStateNull;
       
   345 	// Complete state machine
       
   346 	CompleteMachineBase();
       
   347 	}
       
   348 
       
   349 
       
   350 /** Complete a state transition.
       
   351 This is called by the base class when a state transition has
       
   352 concluded and it provides an opportunity for the state machine 
       
   353 to perform actions required immediately after this transition.
       
   354 
       
   355 The method can also initiate a further change of state. This is
       
   356 relevant when the state machine is required to perform an autonomous
       
   357 transition from one state to another e.g. this occurs when several
       
   358 interactions are required arising from a single external trigger.
       
   359 */  
       
   360 void CX3pStateMachine::PostStateTransition()
       
   361 	{
       
   362 	// Some states are transitory i.e. they require
       
   363 	// an automatic transition to the next state
       
   364 	if (CancelPending() ||
       
   365 		(EStateClientReqRecvd == iCurrentState) ||
       
   366 		(EStateMeasureDataRecvd == iCurrentState) ||
       
   367 		(EStateNetBasedLocSent == iCurrentState) ||
       
   368 		(EStateLocRespRecvd == iCurrentState) ||
       
   369 		((EStateLocSentToNet == iCurrentState) && (LocRespReason() < KErrNone)) ||
       
   370 		(EStateNetSessToClose == iCurrentState) ||
       
   371 		(EStateNetResultSent == iCurrentState) ||
       
   372 		(EStateClientSessToClose == iCurrentState) ||
       
   373 		(EStateSessionsClosed == iCurrentState) ||
       
   374 		(EStateCancelling == iCurrentState)
       
   375 		)
       
   376 		{
       
   377 		// Perform a state transition
       
   378 		PerformStateTransition();
       
   379 		}
       
   380 	}
       
   381 
       
   382 
       
   383 /** Do actions required for a queued request.
       
   384 This currently only initiates another state change but it 
       
   385 has the scope for further actions to be carried out according
       
   386 to the nature of a queued request.
       
   387 */
       
   388 void CX3pStateMachine::DoQueuedRequest(TInt aRequest)
       
   389 	{
       
   390 	switch (aRequest)
       
   391 		{
       
   392 	//case EQueueLocResponse:
       
   393 		// Perform a state transition
       
   394 		//PerformStateTransition();
       
   395 		//break;
       
   396 	case EQueueLocResponse:
       
   397 	case EQueueMeasurementControl:	
       
   398 	case EQueueNetworkResult:
       
   399 		// Only do state transition if not just cancelling.
       
   400 		if (!iStillCancelling)
       
   401 			{
       
   402 			PerformStateTransition();
       
   403 			iStillCancelling = EFalse;
       
   404 			}
       
   405 		break;
       
   406 
       
   407 	default:
       
   408 		User::Panic(KProtocolModulePanic, EProtocolModuleQueueRequestId);
       
   409 		break;
       
   410 		};
       
   411 
       
   412 	}
       
   413 
       
   414 
       
   415 /** Cancel the active procedure
       
   416 */  
       
   417 void CX3pStateMachine::CancelProcedure()
       
   418 	{
       
   419 	// Kill all timers
       
   420 	iX3pReqIssuedTimer->Cancel();
       
   421 	iLocRespTimer->Cancel();
       
   422 	iAssistDataTimer->Cancel();
       
   423 	iFacResultTimer->Cancel();
       
   424 	}
       
   425 
       
   426 /** Set the cancelling flag which stops certain queued transitions occurring
       
   427 */
       
   428 void CX3pStateMachine::SetStillCancelling(TBool aValue)
       
   429 	{
       
   430 	iStillCancelling = aValue;
       
   431 	}
       
   432 
       
   433 /** Timer expired callback.
       
   434 This is called by a CStateTimer object when the timer
       
   435 has expired - the event is identified by aEvent parameter.
       
   436 @param aTimerId The timer event identifier.
       
   437 */
       
   438 void CX3pStateMachine::OnTimerEventL(TInt aTimerId)
       
   439 	{
       
   440 	// Perform relevant action for the expired timer
       
   441 	switch (aTimerId)
       
   442 		{
       
   443 
       
   444 	// X3P request timer
       
   445 	case KX3pReqIssuedTimerEvent:
       
   446 		// Inform protocol manager
       
   447 		Observer().MeasurementControlTimeout();
       
   448 		break;
       
   449 
       
   450 	// Additional assistance data timer
       
   451 	case KAssistDataTimerEvent:
       
   452 		// Ensure assistance data action is performed upon cancellation
       
   453 		iAssistanceDataActionRequired = ETrue;
       
   454 		iLocRespReason = KErrTimedOut;
       
   455 		// Inform protocol manager
       
   456 		Observer().MeasurementControlTimeout();
       
   457 		break;
       
   458 
       
   459 	// Location response timer
       
   460 	case KLocRespTimerEvent:
       
   461 		iLocRespReason = KErrTimedOut;
       
   462 		CancelMachine(ECancelClientTimeout);
       
   463 		break;
       
   464 		
       
   465 	// Facility result timer
       
   466 	case KX3pFacResultTimerEvent:
       
   467 		CancelMachine(ECancelNetworkTimeout);
       
   468 		break;
       
   469 		
       
   470 	// Ignore unknown timer events
       
   471 	default:
       
   472 		break;
       
   473 
       
   474 		};
       
   475 
       
   476 	}
       
   477 
       
   478 
       
   479 /** Timer callback error handler.
       
   480 This is called if the timer expiry callback leaves.
       
   481 @see CX3pStateMachine::OnTimerEventL()
       
   482 @param aTimerId The timer event identifier.
       
   483 @param aError Error value.
       
   484 */
       
   485 TInt CX3pStateMachine::OnTimerError(TInt /*aTimerId*/, TInt aError)
       
   486 	{
       
   487 	return aError;
       
   488 	}
       
   489 
       
   490 
       
   491 /** Handle Measurement Control timeout
       
   492 */
       
   493 void CX3pStateMachine::MeasurementControlTimeout()
       
   494 	{
       
   495 	// Cancel procedure
       
   496 	CancelMachine(ECancelNetworkTimeout, KErrTimedOut);
       
   497 	}
       
   498 
       
   499 
       
   500 /** Handle LBS request for X3P
       
   501 @param aDest The destination for this transmit request
       
   502 */
       
   503 void CX3pStateMachine::X3pReq(const TLbsNetSessionId& aNewSessionId, const TDesC& aDest)
       
   504 	{
       
   505 	// Store the supplied ID information
       
   506 	SessionId(aNewSessionId);
       
   507 
       
   508 	// Initialise the new procedure
       
   509 	InitialiseProcedure();
       
   510 
       
   511 	// Store destination
       
   512 	StoreDestination(aDest);
       
   513 
       
   514 	// Perform a state transition
       
   515 	PerformStateTransition();
       
   516 	}
       
   517 
       
   518 
       
   519 /** Queue a LBS request for X3P
       
   520 @param aDest The destination for this transmit request
       
   521 */
       
   522 void CX3pStateMachine::QueueX3pReq(const TLbsNetSessionId& aNewSessionId, const TDesC& aDest)
       
   523 	{
       
   524 	// Store the session ID
       
   525 	QueueSessionId(aNewSessionId);
       
   526 
       
   527 	// Store destination
       
   528 	QueueDestination(aDest);
       
   529 
       
   530 	CStateMachineBase::SetMachineAsQueued();
       
   531 	}
       
   532 	
       
   533 
       
   534 /** Handle Network Session Result
       
   535 @param aResult The error result from network session closure.
       
   536 @param aPosInfo A pointer to final result location information from the network.
       
   537 	This can be null if there is not final position provided.
       
   538 */
       
   539 void CX3pStateMachine::SessionResult(TInt aResult, const TPositionInfoBase* aPosInfo)
       
   540 	{
       
   541 	// Kill timer related to the facility result
       
   542 	iFacResultTimer->Cancel();
       
   543 
       
   544 	iNetSessionResult = aResult; // does this result say anything about the validity of the position?
       
   545 
       
   546 	// Is a position provided?
       
   547 	if (aPosInfo)
       
   548 		{
       
   549 		// Store network resulting location
       
   550 		StoreNetResultLoc(*aPosInfo);
       
   551 		iIsNetResultLocAvailable = ETrue;
       
   552 		}
       
   553 	else
       
   554 		{
       
   555 		iIsNetResultLocAvailable = EFalse;
       
   556 		}
       
   557 
       
   558 	// Is state machine inactive?
       
   559 	if (!IsActive())
       
   560 		{
       
   561 		// Perform a state transition
       
   562 		PerformStateTransition();
       
   563 		}
       
   564 	else
       
   565 		{
       
   566 		// Queue request
       
   567 		iQueue->AddRequest(EQueueNetworkResult);
       
   568 		}
       
   569 	}
       
   570 
       
   571 /** Start previously queued state machine.
       
   572 */  
       
   573 void CX3pStateMachine::StartQueuedMachine()
       
   574 	{
       
   575 	X3pReq(iQueueSessionId, iQueueDestination);
       
   576 	}
       
   577 
       
   578 
       
   579 /** Handle LBS Location response
       
   580 @param aReason Location response error reason.
       
   581 @param aPosInfo The location response from LBS.
       
   582 */
       
   583 void CX3pStateMachine::LocationResp(TInt aReason, const TPositionInfoBase& aPosInfo)
       
   584 	{
       
   585 	// Store location response data
       
   586 	StoreLocationResp(aReason, aPosInfo);
       
   587 
       
   588 	// Kill the timer related to location response expected by network
       
   589 	iLocRespTimer->Cancel();
       
   590 
       
   591 	// Is the state machine inactive?
       
   592 	if (!IsActive())
       
   593 		{
       
   594 		// Perform a state transition
       
   595 		PerformStateTransition();
       
   596 		}
       
   597 	else
       
   598 		{
       
   599 		// Queue the request
       
   600 		iQueue->AddRequest(EQueueLocResponse);
       
   601 		}
       
   602 	}
       
   603 
       
   604 
       
   605 /** Handle Network Measurement Control indication.
       
   606 A measurement control indication has been received from the network.
       
   607 Note: At this stage the assistance data has already been stored by the
       
   608 protocol manager and is thus not passed into this method.
       
   609 
       
   610 @param aPosInfo Reference location provided in the measuerment control
       
   611 @param aQuality Location request quality specified in the measuerment control
       
   612 */
       
   613 void CX3pStateMachine::MeasurementControlInd(const TPositionInfoBase& aPosInfo,
       
   614 	const TLbsNetPosRequestQuality& aQuality, const TLbsNetPosRequestMethod& aPosMethod)
       
   615 	{
       
   616 	// Kill timer related to the X3P request
       
   617 	iX3pReqIssuedTimer->Cancel();
       
   618 
       
   619 	// Perform base class actions
       
   620 	CStateMachineBase::MeasurementControlInd(aPosInfo, aQuality, aPosMethod);
       
   621 
       
   622 	// Is the state machine inactive?
       
   623 	if (!IsActive())
       
   624 		{
       
   625 		// Perform a state transition
       
   626 		PerformStateTransition();
       
   627 		}
       
   628 	else
       
   629 		{
       
   630 		// Queue the request
       
   631 		iQueue->AddRequest(EQueueMeasurementControl);
       
   632 		}
       
   633 	}
       
   634 
       
   635 
       
   636 /** Handle Network Measurement Control Error indication
       
   637 This is called by the protocol manager durinq an active X3P when
       
   638 a measurement control error is received from the network.
       
   639 */
       
   640 void CX3pStateMachine::MeasurementControlErrorInd(TInt aReason)
       
   641 	{
       
   642 	TBool cancelRequired = EFalse;
       
   643 	TBool assistActionRequired = ETrue;
       
   644 
       
   645 	// If there is no outstanding assistance data request then 
       
   646 	// inhibit assistance data error responses.
       
   647 	if (!iAssistDataTimer->IsActive())
       
   648 		{
       
   649 		assistActionRequired = EFalse;
       
   650 		}
       
   651 
       
   652 	// If this is the first measurement control received
       
   653 	// Then we shall need to cancel the state machine
       
   654 	if (!IsLocReqReceived() || (KErrCancel == aReason))
       
   655 		{
       
   656 		// Kill timer related to the X3P request
       
   657 		iX3pReqIssuedTimer->Cancel();
       
   658 		cancelRequired = ETrue;
       
   659 		}
       
   660 
       
   661 	// Perform base class actions
       
   662 	CStateMachineBase::HandleMeasureControlError(cancelRequired, aReason);
       
   663 
       
   664 	// Ensure assistance data action only happens if necessary
       
   665 	iAssistanceDataActionRequired = assistActionRequired;
       
   666 	}
       
   667 
       
   668 
       
   669 /** Handle a network error indication.
       
   670 */  
       
   671 void CX3pStateMachine::NetworkErrorInd()
       
   672 	{
       
   673 	// Do we need to report assistance data errors?
       
   674 	if (!IsLocReqReceived())
       
   675 		{
       
   676 		iAssistanceDataActionRequired = ETrue;
       
   677 		}
       
   678 
       
   679 	// Perform base class actions
       
   680 	CStateMachineBase::NetworkErrorInd();
       
   681 	}
       
   682 
       
   683 /** Client close reason.
       
   684 This is called by state handlers to determine what reason to
       
   685 provide to the client for the client session closing.
       
   686 @return TInt Reason value.
       
   687 */
       
   688 TInt CX3pStateMachine::ClientCloseReason()  const
       
   689 	{
       
   690 	TInt reason = KErrNone;
       
   691 
       
   692 	if (KErrPositionHighPriorityReceive == iClientCancelReason)
       
   693 		{
       
   694 		reason = iClientCancelReason;
       
   695 		}
       
   696 	else if (KErrNone == iNetworkCancelReason)
       
   697 		{
       
   698 		switch (iCancelSource)
       
   699 			{
       
   700 		case ECancelNetworkCancel:
       
   701 			reason = KErrCancel;
       
   702 			break;
       
   703 
       
   704 		case ECancelNetworkError:
       
   705 			reason = KErrDisconnected;
       
   706 			break;
       
   707 
       
   708 		case ECancelClientTimeout:
       
   709 		case ECancelNetworkTimeout:
       
   710 			reason = KErrTimedOut;
       
   711 			break;
       
   712 
       
   713 		case ECancelClientCancel:
       
   714 			{
       
   715 			reason = iClientCancelReason;
       
   716 			break;
       
   717 			}
       
   718 			
       
   719 		case ECancelNone:
       
   720 			reason = LocRespReason();
       
   721 			break;
       
   722 
       
   723 		case ECancelClientCancelSilent:
       
   724 		case ECancelClosing:
       
   725 			break;
       
   726 
       
   727 		default:
       
   728 			User::Panic(KProtocolModulePanic, EProtocolModuleCancelSource);
       
   729 			break;
       
   730 			};
       
   731 		}
       
   732 	else
       
   733 		{
       
   734 		reason = iNetworkCancelReason;
       
   735 		}
       
   736 
       
   737 	return reason;
       
   738 	}
       
   739