networkprotocolmodules/networkprotocolmodule/LbsProtocolModule/src/cmtlrstatemachine.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 MT-LR protocol state machine.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @released
       
    23 */
       
    24 
       
    25 #include "cmtlrstatemachine.h"
       
    26 #include "cmtlrstatehandler.h"
       
    27 #include <e32property.h>
       
    28 #include <lbs/test/lbsnetsimstatus.h>
       
    29 
       
    30 /** KMtLrReqIssuedTimerEvent
       
    31 Identity of timer for when MT-LR request issued by network
       
    32 */
       
    33 const TInt KMtLrReqIssuedTimerEvent = 0x10;
       
    34 
       
    35 /** KMtLrReqIssuedTimerDurationInSec
       
    36 Timer duration for when MT-LR request issued by network
       
    37 */
       
    38 const TInt KMtLrReqIssuedTimerDurationInSec = 30;
       
    39 
       
    40 /** KMeasureControlTimerEvent
       
    41 Identity of timer for when measurement control expected by LBS
       
    42 */
       
    43 const TInt KMeasureControlTimerEvent = 0x20;
       
    44 
       
    45 /** KMeasureControlTimerDurationInSec
       
    46 Timer duration for when measurement control expected by LBS
       
    47 */
       
    48 const TInt KMeasureControlTimerDurationInSec = 20;
       
    49 
       
    50 /** KLocRespTimerEvent
       
    51 Identity of timer for when location response expected by network
       
    52 */
       
    53 const TInt KLocRespTimerEvent = 0x30;
       
    54 
       
    55 /** KLocRespTimerDurationInSec
       
    56 Timer duration for when location response expected by network
       
    57 */
       
    58 const TInt KLocRespTimerDurationInSec = 64;
       
    59 
       
    60 /** KMaxQueueEntry
       
    61 Maximum entries in this state machine request queue.
       
    62 */
       
    63 const TInt KMaxQueueEntry = 5;
       
    64 
       
    65 
       
    66 /** Static constructor.
       
    67 @param aObserver Reference to state machine observer.
       
    68 @return A new instance of the CMtLrStateMachine class
       
    69 */  
       
    70 CMtLrStateMachine* CMtLrStateMachine::NewL(MStateMachineObserver& aObserver)
       
    71 	{
       
    72 	CMtLrStateMachine* self = new (ELeave) CMtLrStateMachine(aObserver);
       
    73 	CleanupStack::PushL(self);
       
    74 	self->ConstructL();
       
    75 	CleanupStack::Pop(self);
       
    76 	return self;
       
    77 	}
       
    78 
       
    79 
       
    80 /** Standard constructor.
       
    81 @param aObserver Reference to state machine observer.
       
    82 */  
       
    83 CMtLrStateMachine::CMtLrStateMachine(MStateMachineObserver& aObserver)
       
    84 : CStateMachineBase(aObserver)
       
    85 	{
       
    86 	}
       
    87 
       
    88 
       
    89 /** Standard destructor.
       
    90 */  
       
    91 CMtLrStateMachine::~CMtLrStateMachine()
       
    92 	{
       
    93 	delete iLocRespTimer;
       
    94 	delete iMeasureControlTimer;
       
    95 	delete iMtLrReqIssuedTimer;
       
    96 	}
       
    97 
       
    98 
       
    99 /** Private second-stage constructor.
       
   100 */  
       
   101 void CMtLrStateMachine::ConstructL()
       
   102 	{
       
   103 	CActiveScheduler::Add(this);
       
   104 
       
   105 	// Create state handler
       
   106 	iStateHandler = CMtLrStateHandler::NewL(*this);
       
   107 
       
   108 	// Create timers used during MT-LR protocol procedure
       
   109 	iMtLrReqIssuedTimer = CLbsCallbackTimer::NewL(*this);
       
   110 	iMeasureControlTimer = CLbsCallbackTimer::NewL(*this);
       
   111 	iLocRespTimer = CLbsCallbackTimer::NewL(*this);
       
   112 	iAssistDataTimer = CLbsCallbackTimer::NewL(*this);
       
   113 
       
   114 	// Create request queue
       
   115 	iQueue = CStateQueue::NewL(KMaxQueueEntry);
       
   116 	}
       
   117 
       
   118 
       
   119 /** Retrieve current MT-LR State
       
   120 @return TMtLrState Current MT-LR state
       
   121 */
       
   122 CMtLrStateMachine::TMtLrState CMtLrStateMachine::CurrentState()
       
   123 	{
       
   124 	return iCurrentState;
       
   125 	}
       
   126 
       
   127 	
       
   128 /** Start MT-LR request timer
       
   129 This is called when an MT-LR request is received from the network
       
   130 and it requires a response before the timer expires.
       
   131 */
       
   132 void CMtLrStateMachine::StartMtLrReqTimer()
       
   133 	{
       
   134 	if(iMtLrReqIssuedTimer->IsActive())
       
   135 		{
       
   136 		iMtLrReqIssuedTimer->Cancel();
       
   137 		}
       
   138 	iMtLrReqIssuedTimer->EventAfter(TTimeIntervalSeconds(KMtLrReqIssuedTimerDurationInSec), KMtLrReqIssuedTimerEvent);
       
   139 	}
       
   140 
       
   141 	
       
   142 /** Start Measure Control timer
       
   143 This is called when Measurement Control is expected by LBS.
       
   144 */
       
   145 void CMtLrStateMachine::StartMeasureControlTimer()
       
   146 	{
       
   147 	if(iMeasureControlTimer->IsActive())
       
   148 		{
       
   149 		iMeasureControlTimer->Cancel();
       
   150 		}
       
   151 	iMeasureControlTimer->EventAfter(TTimeIntervalSeconds(KMeasureControlTimerDurationInSec), KMeasureControlTimerEvent);
       
   152 	}
       
   153 
       
   154 	
       
   155 /** Start location response timer
       
   156 The state handler calls this when it has sent a location request
       
   157 to the client and requires a response before the timer expires.
       
   158 */
       
   159 void CMtLrStateMachine::StartLocRespTimer()
       
   160 	{
       
   161 	if(iLocRespTimer->IsActive())
       
   162 		{
       
   163 		iLocRespTimer->Cancel();
       
   164 		}
       
   165 	iLocRespTimer->EventAfter(TTimeIntervalSeconds(KLocRespTimerDurationInSec), KLocRespTimerEvent);
       
   166 	}
       
   167 
       
   168 
       
   169 /** Privacy requestor information
       
   170 This is called by state handlers to retrieve the most
       
   171 recent privacy request info.
       
   172 @return TLbsExternalRequestInfo Currently held privacy requestor information
       
   173 */
       
   174 const TLbsExternalRequestInfo& CMtLrStateMachine::PrivacyReqInfo() const
       
   175 	{
       
   176 	return iPrivacyReqInfo;
       
   177 	}
       
   178 
       
   179 
       
   180 /** Privacy request
       
   181 This is called by state handlers to retrieve the most
       
   182 recent privacy request.
       
   183 @return const TLbsNetPosRequestPrivacy& Currently held privacy request
       
   184 */
       
   185 const TLbsNetPosRequestPrivacy& CMtLrStateMachine::PrivacyReq() const
       
   186 	{
       
   187 	return iPrivacyRequest;
       
   188 	}
       
   189 
       
   190 
       
   191 /** Privacy response value
       
   192 This is called by state handlers to retrieve the most
       
   193 recent privacy response.
       
   194 @return TLbsPrivacyResponse Currently held privacy response value
       
   195 */
       
   196 const CLbsNetworkProtocolBase::TLbsPrivacyResponse& CMtLrStateMachine::PrivacyResponseValue() const
       
   197 	{
       
   198 	return iPrivacyResp;
       
   199 	}
       
   200 
       
   201 
       
   202 /** Has privacy response been handled.
       
   203 This is called to determine if privacy response handled.
       
   204 @return TBool ETrue if privacy response handled
       
   205 */
       
   206 TBool CMtLrStateMachine::IsPrivacyResponseHandled() const
       
   207 	{
       
   208 	return iPrivacyResponseHandled;
       
   209 	}
       
   210 
       
   211 
       
   212 /** Has privacy response been handled.
       
   213 This is called to determine if privacy response handled.
       
   214 @return TBool ETrue if privacy response handled
       
   215 */
       
   216 TBool CMtLrStateMachine::IsRejectedWaitingMeasureControl() const
       
   217 	{
       
   218 	return (EStateClientSessToCloseWaitMeasure == iCurrentState);
       
   219 	}
       
   220 
       
   221 
       
   222 /** Is this an emergency situation.
       
   223 This is called to determine if there is an emergency situation for which
       
   224 an MT-LR is being requested.
       
   225 @return TBool ETrue if emergency situation exists
       
   226 */
       
   227 TBool CMtLrStateMachine::IsEmergency() const
       
   228 	{
       
   229 #pragma message("Emergency timers not implemented.")
       
   230 	// Retrieve current value of emergency property published by NetSim
       
   231 	TBool stateValue = EFalse;
       
   232 	RProperty::Get(TUid::Uid(KLbsNetSimStatus), KLbsEmergencyStatus, stateValue);
       
   233 	return stateValue;
       
   234 	}
       
   235 
       
   236 
       
   237 /** Initialise internal state attributes.
       
   238 This is used when new MT-LR procedure commences.
       
   239 */
       
   240 void CMtLrStateMachine::InitialiseProcedure()
       
   241 	{
       
   242 	// Initialise state machine
       
   243 	InitialiseMachineBase();
       
   244 
       
   245 	iPrivacyResponseRecvd = EFalse;
       
   246 	iPrivacyResponseHandled = EFalse;
       
   247 
       
   248 	ASSERT(iStateHandler != NULL);
       
   249 	iStateHandler->Initialise();
       
   250 	}
       
   251 	
       
   252 
       
   253 /** Procedure is done.
       
   254 */  
       
   255 void CMtLrStateMachine::ProcedureDone()
       
   256 	{
       
   257 	// If a location response error has been reported then forward it to network
       
   258 	if (KErrNone != LocRespReason())
       
   259 		{
       
   260 		CNetworkInterface::TNetworkError netError = 
       
   261 						Observer().Network()->LocationResp(LocRespReason());
       
   262 		// Handle network-related error
       
   263 		if (CNetworkInterface::ENone != netError)
       
   264 			{
       
   265 			Observer().NetworkErrorReported();
       
   266 			}
       
   267 		}
       
   268 	// Procedure is complete
       
   269 	CompleteProcedure();
       
   270 	}
       
   271 	
       
   272 
       
   273 /** Prepare state transition.
       
   274 */  
       
   275 void CMtLrStateMachine::PreStateTransition()
       
   276 	{
       
   277 	}
       
   278 	
       
   279 
       
   280 /** State transition.
       
   281 This method determines the next state to be adopted by the state machine.
       
   282 */
       
   283 void CMtLrStateMachine::StateTransition()
       
   284 	{
       
   285 	if (CancelPending())
       
   286 		{
       
   287 		SetMachineAsCancelling();
       
   288 		iCurrentState = EStateCancelling;
       
   289 		}
       
   290 	else
       
   291 		{
       
   292 		// Set new state		
       
   293 		switch (iCurrentState)
       
   294 			{
       
   295 			
       
   296 		case EStateNull:
       
   297 			iCurrentState = EStateNetReqRecvd;
       
   298 			break;
       
   299 			
       
   300 		case EStateNetReqRecvd:
       
   301 			iCurrentState = EStatePrivacySessStarted;
       
   302 			iIsPrivacyRespBeforeMeasureControl = EFalse;
       
   303 			break;
       
   304 			
       
   305 		case EStatePrivacySessStarted:
       
   306 			// Location request received?
       
   307 			if (iIsLocReqReceived)
       
   308 				{
       
   309 				iCurrentState = EStateMeasureDataRecvd;
       
   310 				}
       
   311 			// Privacy response received?
       
   312 			else if (iPrivacyResponseRecvd)
       
   313 				{
       
   314 				iIsPrivacyRespBeforeMeasureControl = ETrue;
       
   315 				iPrivacyResponseHandled = ETrue;
       
   316 				iCurrentState = EStatePrivacyRespRecvd;
       
   317 
       
   318 				// Start timer for when the measurement control is expected
       
   319 				StartMeasureControlTimer();
       
   320 				}
       
   321 			break;
       
   322 			
       
   323 		case EStatePrivacyRespRecvd:
       
   324 			// Privacy not accepted?
       
   325 			if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp)
       
   326 				{
       
   327 				iCurrentState = EStatePrivacyReject;
       
   328 				}
       
   329 			else
       
   330 				{
       
   331 				iCurrentState = EStateMeasureDataRecvd;
       
   332 				}
       
   333 			break;
       
   334 			
       
   335 		case EStatePrivacyRespRecvdAfterMeasure:
       
   336 			// Privacy not accepted?
       
   337 			if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp)
       
   338 				{
       
   339 				iCurrentState = EStatePrivacyRejectAfterMeasure;
       
   340 				}
       
   341 			else
       
   342 				{
       
   343 				iCurrentState = EStateLocRespRecvd;
       
   344 				}
       
   345 			break;
       
   346 			
       
   347 		case EStatePrivacyReject:
       
   348 			iCurrentState = EStateClientSessToCloseWaitMeasure;
       
   349 			break;
       
   350 			
       
   351 		case EStatePrivacyRejectAfterMeasure:
       
   352 			iCurrentState = EStateLocRespRecvd;
       
   353 			break;
       
   354 			
       
   355 		case EStateMeasureDataRecvd:
       
   356 			iCurrentState = EStateNetBasedLocSent;
       
   357 			break;
       
   358 			
       
   359 		case EStateNetBasedLocSent:
       
   360 			iIsMeasureControlHandled = ETrue;
       
   361 			// Was privacy already rejected
       
   362 			if (iIsPrivacyRespBeforeMeasureControl &&
       
   363 				CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp)
       
   364 				{
       
   365 				ProcedureDone();
       
   366 				}
       
   367 			else
       
   368 				{
       
   369 				iCurrentState = EStateLocReqByNet;
       
   370 				}
       
   371 			break;
       
   372 			
       
   373 		case EStateLocReqByNet:
       
   374 			iCurrentState = iIsPrivacyRespBeforeMeasureControl ? 
       
   375 							EStateLocRespRecvd : EStatePrivacyRespRecvdAfterMeasure;
       
   376 			break;
       
   377 			
       
   378 		case EStateLocRespRecvd:
       
   379 			iCurrentState = EStateLocSentToNet;
       
   380 			break;
       
   381 			
       
   382 		case EStateLocSentToNet:
       
   383 			iCurrentState = EStateClientSessToCloseAfterMeasure;
       
   384 			break;
       
   385 			
       
   386 		case EStateClientSessToCloseWaitMeasure:
       
   387 			iCurrentState = EStateMeasureDataRecvd;
       
   388 			break;
       
   389 			
       
   390 		case EStateClientSessToCloseWaitLocResp:
       
   391 			// We are waiting for location response from LBS after the
       
   392 			// preceding session closes. Check to see if we have timeout
       
   393 			// otherwise we must have received the response.
       
   394 			if (Cancelling() && (KErrTimedOut == iLocRespReason))
       
   395 				{
       
   396 				iCurrentState = EStateCancelling;
       
   397 				}
       
   398 			else
       
   399 				{
       
   400 				ProcedureDone();
       
   401 				}
       
   402 			break;
       
   403 			
       
   404 		case EStateClientSessToCloseAfterMeasure:
       
   405 			ProcedureDone();
       
   406 			break;
       
   407 			
       
   408 		case EStateSessionsClosed:
       
   409 			// Procedure has completed
       
   410 			CompleteProcedure();
       
   411 			break;
       
   412 
       
   413 		case EStateCancelling:
       
   414 			switch (iCancelSource)
       
   415 				{
       
   416 			case ECancelNone:
       
   417 			case ECancelClosing:
       
   418 			case ECancelClientCancel:
       
   419 			case ECancelClientCancelSilent:
       
   420 				CompleteProcedure();
       
   421 				break;
       
   422 
       
   423 			case ECancelNetworkError:
       
   424 				iCurrentState = EStateClientSessToCloseAfterMeasure;
       
   425 				break;
       
   426 
       
   427 			case ECancelNetworkTimeout:
       
   428 				// We were waiting for measurement control.
       
   429 				// Was privacy rejected?
       
   430 				if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp)
       
   431 					{
       
   432 					ProcedureDone();
       
   433 					}
       
   434 				else
       
   435 					{
       
   436 					iCurrentState = EStateClientSessToCloseAfterMeasure;
       
   437 					}
       
   438 				break;
       
   439 
       
   440 			case ECancelClientTimeout:
       
   441 				// We were either waiting for a location response or a privacy response
       
   442 				// Privacy response will timeout first, but we may need to still wait for
       
   443 				// a location response.
       
   444 				if (!iPrivacyResponseRecvd && iIsMeasureControlHandled && 
       
   445 					(KErrTimedOut != iLocRespReason))
       
   446 					{
       
   447 					iCurrentState = EStateClientSessToCloseWaitLocResp;
       
   448 					}
       
   449 				else
       
   450 					{
       
   451 					iCurrentState = EStateClientSessToCloseAfterMeasure;
       
   452 					}
       
   453 				break;
       
   454 
       
   455 			case ECancelNetworkCancel:
       
   456 				iCurrentState = EStateClientSessToCloseAfterMeasure;
       
   457 				break;
       
   458 
       
   459 			default:
       
   460 				User::Panic(KProtocolModulePanic, EProtocolModuleCancelSource);
       
   461 				break;
       
   462 				};
       
   463 			break;
       
   464 
       
   465 		default:
       
   466 			User::Panic(KProtocolModulePanic, EProtocolModuleMtLrState);
       
   467 			break;
       
   468 			};
       
   469 		}
       
   470 
       
   471 	}
       
   472 
       
   473 
       
   474 /** Complete the procedure.
       
   475 */  
       
   476 void CMtLrStateMachine::CompleteProcedure()
       
   477 	{
       
   478 	iCurrentState = EStateNull;
       
   479 	// Complete state machine
       
   480 	CompleteMachineBase();
       
   481 	}
       
   482 
       
   483 
       
   484 /** Complete state transition.
       
   485 This is called by the base class when a state transition has
       
   486 concluded and it provides an opportunity for the state machine 
       
   487 to perform actions required immediately after this transition.
       
   488 
       
   489 The method can also initiate a further change of state. This is
       
   490 relevant when the state machine is required to perform an autonomous
       
   491 transition from one state to another e.g. this occurs when several
       
   492 interactions are required arising from a single external trigger.
       
   493 */  
       
   494 void CMtLrStateMachine::PostStateTransition()
       
   495 	{
       
   496 	// Some states are transitory i.e. they require
       
   497 	// an automatic transition to the next state
       
   498 	if ( CancelPending() ||
       
   499 		 (EStateNetReqRecvd == iCurrentState) ||
       
   500 	 	 ((CLbsNetworkProtocolBase::EPrivacyResponseAccepted != PrivacyResponseValue()) &&
       
   501 		  ((EStatePrivacyRespRecvd == iCurrentState) || (EStatePrivacyRespRecvdAfterMeasure == iCurrentState))) ||
       
   502 	 	 (EStatePrivacyReject == iCurrentState) ||
       
   503 	 	 (EStateMeasureDataRecvd == iCurrentState) ||
       
   504 	 	 (EStateNetBasedLocSent == iCurrentState) ||
       
   505 	 	 (EStateLocRespRecvd == iCurrentState) ||
       
   506 	 	 (EStateLocSentToNet == iCurrentState) ||
       
   507 	 	 (EStateClientSessToCloseAfterMeasure == iCurrentState) ||
       
   508 	 	 (EStateSessionsClosed == iCurrentState) ||
       
   509 	 	 (EStateCancelling == iCurrentState)
       
   510 	   )
       
   511 		{
       
   512 		// Perform a state transition
       
   513 		PerformStateTransition();
       
   514 		}
       
   515 	}
       
   516 
       
   517 
       
   518 /** Do actions required for a queued request.
       
   519 This currently only initiates another state change but it 
       
   520 has the scope for further actions to be carried out according
       
   521 to the nature of a queued request.
       
   522 */
       
   523 void CMtLrStateMachine::DoQueuedRequest(TInt aRequest)
       
   524 	{
       
   525 	switch (aRequest)
       
   526 		{
       
   527 	case EQueuePrivacyResponse:
       
   528 	case EQueueLocResponse:
       
   529 	case EQueueMeasurementControl:
       
   530 		// Perform a state transition
       
   531 		PerformStateTransition();
       
   532 		break;
       
   533 
       
   534 	default:
       
   535 		User::Panic(KProtocolModulePanic, EProtocolModuleQueueRequestId);
       
   536 		break;
       
   537 		};
       
   538 
       
   539 	}
       
   540 
       
   541 
       
   542 /** Cancel active procedure
       
   543 */  
       
   544 void CMtLrStateMachine::CancelProcedure()
       
   545 	{
       
   546 	// Kill all timers
       
   547 	iMtLrReqIssuedTimer->Cancel();
       
   548 	iMeasureControlTimer->Cancel();
       
   549 	iLocRespTimer->Cancel();
       
   550 	iAssistDataTimer->Cancel();
       
   551 	}
       
   552 
       
   553 
       
   554 /** Timer expired callback.
       
   555 This is called by a CStateTimer object when the timer
       
   556 has expired - the event is identified by aEvent parameter.
       
   557 @param aTimerId The timer event identifier.
       
   558 */
       
   559 void CMtLrStateMachine::OnTimerEventL(TInt aTimerId)
       
   560 	{
       
   561 	// Perform relevant action for the expired timer
       
   562 	switch (aTimerId)
       
   563 		{
       
   564 
       
   565 	// MT-LR request timer
       
   566 	case KMtLrReqIssuedTimerEvent:
       
   567 		iPrivacyResp = CLbsNetworkProtocolBase::EPrivacyResponseUnknown;
       
   568 		CancelMachine(ECancelClientTimeout);
       
   569 		break;
       
   570 
       
   571 	// Measurement control timer
       
   572 	case KMeasureControlTimerEvent:
       
   573 		// Inform protocol manager
       
   574 		Observer().MeasurementControlTimeout();
       
   575 		break;
       
   576 
       
   577 	// Additional assistance data timer
       
   578 	case KAssistDataTimerEvent:
       
   579 		// Ensure assistance data action is performed upon cancellation
       
   580 		iAssistanceDataActionRequired = ETrue;
       
   581 		// Inform protocol manager
       
   582 		Observer().MeasurementControlTimeout();
       
   583 		break;
       
   584 
       
   585 	// Location response timer
       
   586 	case KLocRespTimerEvent:
       
   587 		iLocRespReason = KErrTimedOut;
       
   588 		CancelMachine(ECancelClientTimeout);
       
   589 		break;
       
   590 
       
   591 	// Ignore unknown timer events
       
   592 	default:
       
   593 		break;
       
   594 
       
   595 		};
       
   596 
       
   597 	}
       
   598 
       
   599 
       
   600 /** Timer callback error handler.
       
   601 This is called if the timer expiry callback leaves.
       
   602 @see CMtLrStateMachine::OnTimerEventL()
       
   603 @param aTimerId The timer event identifier.
       
   604 @param aError Error value.
       
   605 */
       
   606 TInt CMtLrStateMachine::OnTimerError(TInt /*aTimerId*/, TInt aError)
       
   607 	{
       
   608 	return aError;
       
   609 	}
       
   610 
       
   611 
       
   612 /** Handle Measurement Control timeout
       
   613 */
       
   614 void CMtLrStateMachine::MeasurementControlTimeout()
       
   615 	{
       
   616 	// Privacy not rejected?
       
   617 	if (CLbsNetworkProtocolBase::EPrivacyResponseRejected != iPrivacyResp)
       
   618 		{
       
   619 		iLocRespReason = KErrTimedOut;
       
   620 		CancelMachine(ECancelNetworkTimeout);
       
   621 		}
       
   622 	else
       
   623 		{
       
   624 		CancelMachine(ECancelNone);
       
   625 		}
       
   626 	}
       
   627 
       
   628 
       
   629 /** Handle LBS Location response
       
   630 @param aReason Location response error reason.
       
   631 @param aPosInfo The location information response from LBS.
       
   632 */
       
   633 void CMtLrStateMachine::LocationResp(TInt aReason, const TPositionInfoBase& aPosInfo)
       
   634 	{
       
   635 	// Store location response data
       
   636 	StoreLocationResp(aReason, aPosInfo);
       
   637 
       
   638 	// Kill the timer related to location response expected by network
       
   639 	iLocRespTimer->Cancel();
       
   640 
       
   641 	// Perform a state transition
       
   642 	if (!IsActive())
       
   643 		{
       
   644 		PerformStateTransition();
       
   645 		}
       
   646 	else
       
   647 		{
       
   648 		iQueue->AddRequest(EQueueLocResponse);
       
   649 		}
       
   650 	}
       
   651 
       
   652 
       
   653 /** Handle LBS Privacy response
       
   654 @param aResponse Privacy response value
       
   655 */
       
   656 void CMtLrStateMachine::PrivacyResp(const CLbsNetworkProtocolBase::TLbsPrivacyResponse& aResponse)
       
   657 	{
       
   658 	// Kill the timer related to the privacy request
       
   659 	iMtLrReqIssuedTimer->Cancel();
       
   660 
       
   661 	// Store privacy response data
       
   662 	StorePrivacyResp(aResponse);
       
   663 
       
   664 	// Perform a state transition
       
   665 	if (!IsActive())
       
   666 		{
       
   667 		PerformStateTransition();
       
   668 		}
       
   669 	else
       
   670 		{
       
   671 		iQueue->AddRequest(EQueuePrivacyResponse);
       
   672 		}
       
   673 	}
       
   674 
       
   675 
       
   676 /** Handle Network MT-LR request
       
   677 @param aReqInfo External requestor information
       
   678 @param aPrivacy Privacy request information
       
   679 */
       
   680 void CMtLrStateMachine::MtLrReq(const TLbsExternalRequestInfo& aReqInfo,
       
   681 		const TLbsNetPosRequestPrivacy& aPrivacy)
       
   682 	{
       
   683 	// This requires a new session to be started
       
   684 	SessionId(iObserver.NewSessionId());
       
   685 
       
   686 	// Associate location requests with MT-LR
       
   687 	iLocReqType = MLbsNetworkProtocolObserver::EServiceMobileTerminated;
       
   688 
       
   689 	// Initialise the new procedure
       
   690 	InitialiseProcedure();
       
   691 
       
   692 	// Start corresponding timer
       
   693 	StartMtLrReqTimer();
       
   694 
       
   695 	// Store privacy request data
       
   696 	StorePrivacyReq(aReqInfo, aPrivacy);
       
   697 
       
   698 	// Perform a state transition
       
   699 	PerformStateTransition();
       
   700 	}
       
   701 
       
   702 
       
   703 /** Queue a Network MT-LR request
       
   704 @param aReqInfo External requestor information
       
   705 @param aPrivacy Privacy request
       
   706 */
       
   707 void CMtLrStateMachine::QueueMtLrReq(const TLbsExternalRequestInfo& aReqInfo,
       
   708 		const TLbsNetPosRequestPrivacy& aPrivacy)
       
   709 	{
       
   710 	// Store privacy request data
       
   711 	StorePrivacyReq(aReqInfo, aPrivacy);
       
   712 
       
   713 	CStateMachineBase::SetMachineAsQueued();
       
   714 	}
       
   715 	
       
   716 
       
   717 /** Start previously queued state machine.
       
   718 */  
       
   719 void CMtLrStateMachine::StartQueuedMachine()
       
   720 	{
       
   721 	MtLrReq(iPrivacyReqInfo, iPrivacyRequest);
       
   722 	}
       
   723 
       
   724 
       
   725 /** Handle Network MT-LR cancel indication
       
   726 @param aReason The reason for cancelling.
       
   727 */
       
   728 void CMtLrStateMachine::MtLrCancelInd(TInt aReason)
       
   729 	{
       
   730 	// Store location cancel reason
       
   731 	StoreNetLocCancelReason(aReason);
       
   732 
       
   733 	// Cancel procedure
       
   734 	CancelMachine(ECancelNetworkCancel);
       
   735 	}
       
   736 
       
   737 
       
   738 /** Handle Network Measurement Control indication
       
   739 A measurement control indication has been received from the network.
       
   740 Note: At this stage the assistance data has already been stored by the
       
   741 protocol manager and is thus not passed into this method.
       
   742 
       
   743 @param aPosInfo Reference location information provided in the measurement control
       
   744 @param aQuality Location request quality specified in the measuerment control
       
   745 */
       
   746 void CMtLrStateMachine::MeasurementControlInd(const TPositionInfoBase& aPosInfo,
       
   747 			const TLbsNetPosRequestQuality& aQuality, const TLbsNetPosRequestMethod& aPosMethod)
       
   748 	{
       
   749 	// A network induced location request may arise when the MT-LR state machine
       
   750 	// is not active. To handle this we fake a privacy response and proceed with 
       
   751 	// the remainder of MT-LR state handling.
       
   752 	if (CStateMachineBase::EStateReady == State())
       
   753 		{
       
   754 		// Associate location requests with NI-LR
       
   755 		iLocReqType = MLbsNetworkProtocolObserver::EServiceNetworkInduced;
       
   756 
       
   757 		// Initialise the protocol procedure
       
   758 		InitialiseProcedure();
       
   759 
       
   760 		// Fake a privacy response
       
   761 		iPrivacyResponseRecvd = ETrue;
       
   762 		iPrivacyResponseHandled = ETrue;
       
   763 		iIsPrivacyRespBeforeMeasureControl = ETrue;
       
   764 		iPrivacyResp = CLbsNetworkProtocolBase::EPrivacyResponseAccepted;
       
   765 		iCurrentState = EStatePrivacyRespRecvd;
       
   766 		}
       
   767 
       
   768 	// Kill the timer for the receipt of Measurement Control
       
   769 	iMeasureControlTimer->Cancel();
       
   770 
       
   771 	// Perform base class actions
       
   772 	CStateMachineBase::MeasurementControlInd(aPosInfo, aQuality, aPosMethod);
       
   773 
       
   774 	// Is the state machine inactive?
       
   775 	if (!IsActive())
       
   776 		{
       
   777 		// Perform a state transition
       
   778 		PerformStateTransition();
       
   779 		}
       
   780 	else
       
   781 		{
       
   782 		// Queue the request
       
   783 		iQueue->AddRequest(EQueueMeasurementControl);
       
   784 		}
       
   785 	}
       
   786 
       
   787 
       
   788 /** Handle Network Measurement Control Error indication
       
   789 This is called by the protocol manager durinq an active MT-LR when
       
   790 a measurement control error is received from the network.
       
   791 */
       
   792 void CMtLrStateMachine::MeasurementControlErrorInd(TInt aReason)
       
   793 	{
       
   794 	TBool cancelRequired = EFalse;
       
   795 	TBool assistActionRequired = ETrue;
       
   796 
       
   797 	// If there is no outstanding assistance data request then 
       
   798 	// inhibit assistance data error responses.
       
   799 	if (!iAssistDataTimer->IsActive())
       
   800 		{
       
   801 		assistActionRequired = EFalse;
       
   802 		}
       
   803 
       
   804 	// Is cancel required?
       
   805 	if (KErrCancel == aReason)
       
   806 		{
       
   807 		cancelRequired = ETrue;
       
   808 		}
       
   809 
       
   810 	// Kill timer related to the MT-LR request
       
   811 	iMtLrReqIssuedTimer->Cancel();
       
   812 
       
   813 	// Perform base class actions
       
   814 	CStateMachineBase::HandleMeasureControlError(cancelRequired, aReason);
       
   815 
       
   816 	// Ensure assistance data action only happens if necessary
       
   817 	iAssistanceDataActionRequired = assistActionRequired;
       
   818 	}
       
   819 
       
   820 
       
   821 /** Store Privacy request
       
   822 @param aReqInfo External requestor information
       
   823 @param aPrivacy Privacy request
       
   824 */
       
   825 void CMtLrStateMachine::StorePrivacyReq(const TLbsExternalRequestInfo& aReqInfo,
       
   826 				const TLbsNetPosRequestPrivacy& aPrivacy)
       
   827 	{
       
   828 	iPrivacyReqInfo = aReqInfo;
       
   829 	// For emergencies always override the privacy request
       
   830 	if (IsEmergency())
       
   831 		{
       
   832 		iPrivacyRequest.SetRequestAdvice(TLbsNetPosRequestPrivacy::ERequestAdviceNotify);
       
   833 		iPrivacyRequest.SetRequestAction(TLbsNetPosRequestPrivacy::ERequestActionAllow);
       
   834 		}
       
   835 	else
       
   836 		{
       
   837 		iPrivacyRequest = aPrivacy;
       
   838 		}
       
   839 	}
       
   840 
       
   841 
       
   842 /** Store Privacy response
       
   843 @param aPrivacyResp Privacy response value
       
   844 */
       
   845 void CMtLrStateMachine::StorePrivacyResp(const CLbsNetworkProtocolBase::TLbsPrivacyResponse& aPrivacyResp)
       
   846 	{
       
   847 	iPrivacyResponseRecvd = ETrue;
       
   848 	iPrivacyResponseHandled = EFalse;
       
   849 	iPrivacyResp = aPrivacyResp;
       
   850 	if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != PrivacyResponseValue())
       
   851 		{
       
   852 		iLocRespReason = KErrPermissionDenied;
       
   853 		}
       
   854 	}
       
   855 
       
   856 
       
   857 /** Handle a network error indication.
       
   858 */  
       
   859 void CMtLrStateMachine::NetworkErrorInd()
       
   860 	{
       
   861 	// Perform base class actions
       
   862 	CStateMachineBase::NetworkErrorInd();
       
   863 	}
       
   864