networkprotocolmodules/networkprotocolmodule/LbsProtocolModule/src/cmolrstatemachine.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 MO-LR protocol state machine.
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalTechnology
       
    22  @released
       
    23 */
       
    24 
       
    25 #include "cmolrstatemachine.h"
       
    26 #include "cmolrstatehandler.h"
       
    27 
       
    28 
       
    29 /** KMoLrReqIssuedTimerEvent
       
    30 Identity of timer for when MO-LR request issued to network
       
    31 */
       
    32 const TInt KMoLrReqIssuedTimerEvent = 0x100;
       
    33 
       
    34 /** KMoLrReqIssuedTimerDurationInSec
       
    35 Timer duration for when MO-LR request issued to network
       
    36 */
       
    37 const TInt KMoLrReqIssuedTimerDurationInSec = 20;
       
    38 
       
    39 /** KLocRespTimerEvent
       
    40 Identity of timer for when location response expected by network
       
    41 */
       
    42 const TInt KLocRespTimerEvent = 0x200;
       
    43 
       
    44 /** KLocRespTimerDurationInSec
       
    45 Timer duration for when location response expected by network
       
    46 */
       
    47 const TInt KLocRespTimerDurationInSec = 64;
       
    48 
       
    49 /** KFacResultTimerEvent
       
    50 Identity of timer for when facility result expected from network
       
    51 */
       
    52 const TInt KFacResultTimerEvent = 0x300;
       
    53 
       
    54 /** KFacResultTimerDurationInSec
       
    55 Timer duration for when facility result expected from network
       
    56 */
       
    57 const TInt KFacResultTimerDurationInSec = 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 CMoLrStateMachine class
       
    68 */  
       
    69 CMoLrStateMachine* CMoLrStateMachine::NewL(MStateMachineObserver& aObserver)
       
    70 	{
       
    71 	CMoLrStateMachine* self = new (ELeave) CMoLrStateMachine(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 CMoLrStateMachine::CMoLrStateMachine(MStateMachineObserver& aObserver)
       
    83 : CStateMachineBase(aObserver)
       
    84 	{
       
    85 	iLocReqType = MLbsNetworkProtocolObserver::EServiceSelfLocation;
       
    86 	}
       
    87 
       
    88 
       
    89 /** Standard destructor.
       
    90 */  
       
    91 CMoLrStateMachine::~CMoLrStateMachine()
       
    92 	{
       
    93 	delete iFacResultTimer;
       
    94 	delete iLocRespTimer;
       
    95 	delete iMoLrReqIssuedTimer;
       
    96 	}
       
    97 
       
    98 
       
    99 /** Private second-stage constructor.
       
   100 */  
       
   101 void CMoLrStateMachine::ConstructL()
       
   102 	{
       
   103 	CActiveScheduler::Add(this);
       
   104 
       
   105 	// Create state handler
       
   106 	iStateHandler = CMoLrStateHandler::NewL(*this);
       
   107 
       
   108 	// Create timers used during MO-LR protocol procedure
       
   109 	iMoLrReqIssuedTimer = CLbsCallbackTimer::NewL(*this);
       
   110 	iLocRespTimer = CLbsCallbackTimer::NewL(*this);
       
   111 	iFacResultTimer = CLbsCallbackTimer::NewL(*this);
       
   112 	iAssistDataTimer = CLbsCallbackTimer::NewL(*this);
       
   113 
       
   114 	// Create request queue
       
   115 	iQueue = CStateQueue::NewL(KMaxQueueEntry);
       
   116 	}
       
   117 
       
   118 
       
   119 /** Retrieve current MO-Lr state
       
   120 @return TMoLrState Current MO-LR state
       
   121 */
       
   122 CMoLrStateMachine::TMoLrState CMoLrStateMachine::CurrentState()
       
   123 	{
       
   124 	return iCurrentState;
       
   125 	}
       
   126 
       
   127 	
       
   128 /** Start MO-LR request timer
       
   129 The state handler calls this when it has issued an MO-LR request
       
   130 to the network and it requires a response before the timer expires.
       
   131 */
       
   132 void CMoLrStateMachine::StartMoLrReqTimer()
       
   133 	{
       
   134 	if(iMoLrReqIssuedTimer->IsActive())
       
   135 		{
       
   136 		iMoLrReqIssuedTimer->Cancel();
       
   137 		}
       
   138 	iMoLrReqIssuedTimer->EventAfter(TTimeIntervalSeconds(KMoLrReqIssuedTimerDurationInSec), KMoLrReqIssuedTimerEvent);
       
   139 	}
       
   140 
       
   141 	
       
   142 /** Start location response timer
       
   143 The state handler calls this when it has sent a location request
       
   144 to the client and requires a response before the timer expires.
       
   145 */
       
   146 void CMoLrStateMachine::StartLocRespTimer()
       
   147 	{
       
   148 	if(iLocRespTimer->IsActive())
       
   149 		{
       
   150 		iLocRespTimer->Cancel();
       
   151 		}
       
   152 	iLocRespTimer->EventAfter(TTimeIntervalSeconds(KLocRespTimerDurationInSec), KLocRespTimerEvent);
       
   153 	}
       
   154 
       
   155 	
       
   156 /** Start facility result timer
       
   157 The state handler calls this when it has sent a location report
       
   158 to the network and requires a result before the timer expires.
       
   159 */
       
   160 void CMoLrStateMachine::StartFacResultTimer()
       
   161 	{
       
   162 	if(iFacResultTimer->IsActive())
       
   163 		{
       
   164 		iFacResultTimer->Cancel();
       
   165 		}
       
   166 	iFacResultTimer->EventAfter(TTimeIntervalSeconds(KFacResultTimerDurationInSec), KFacResultTimerEvent);
       
   167 	}
       
   168 
       
   169 
       
   170 /** Indicates if location request has been sent to LBS.
       
   171 @return TBool ETrue if location request has been sent to LBS.
       
   172 */  
       
   173 TBool CMoLrStateMachine::IsLocReqSentToLbs() const
       
   174 	{
       
   175 	return iIsLocReqSentToLbs;
       
   176 	}
       
   177 
       
   178 
       
   179 /** Network Result Location.
       
   180 This is called by state handlers to retrieve the most
       
   181 recent reported network result location.
       
   182 @return TPositionInfoBase Currently held network result position
       
   183 */
       
   184 const TPositionInfoBase& CMoLrStateMachine::NetResultLoc() const
       
   185 	{
       
   186 	return iNetResultPosInfo;
       
   187 	}
       
   188 
       
   189 
       
   190 /** Store network resulting location
       
   191 @param aPosInfo Network result location information
       
   192 */
       
   193 void CMoLrStateMachine::StoreNetResultLoc(const TPositionInfoBase& aPosInfo)
       
   194 	{
       
   195 	iNetResultPosInfo = reinterpret_cast <const TPositionInfo&> (aPosInfo);
       
   196 	}
       
   197 
       
   198 
       
   199 /** Initialise internal state attributes.
       
   200 This is used when new MO-LR procedure commences.
       
   201 */
       
   202 void CMoLrStateMachine::InitialiseProcedure()
       
   203 	{
       
   204 	// Initialise state machine
       
   205 	InitialiseMachineBase();
       
   206 
       
   207 	iIsLocReqSentToLbs = EFalse;
       
   208 	iIsNetResultLocAvailable = EFalse;
       
   209 
       
   210 	ASSERT(iStateHandler != NULL);
       
   211 	iStateHandler->Initialise();
       
   212 	}
       
   213 	
       
   214 
       
   215 /** Prepare state transition.
       
   216 */  
       
   217 void CMoLrStateMachine::PreStateTransition()
       
   218 	{
       
   219 	}
       
   220 	
       
   221 
       
   222 /** State transition.
       
   223 This method determines the next state to be adopted by the state machine.
       
   224 */  
       
   225 void CMoLrStateMachine::StateTransition()
       
   226 	{
       
   227 	if (CancelPending())
       
   228 		{
       
   229 		SetMachineAsCancelling();
       
   230 		iCurrentState = EStateCancelling;
       
   231 		}
       
   232 	else
       
   233 		{
       
   234 		// Set new state		
       
   235 		switch (iCurrentState)
       
   236 			{
       
   237 			
       
   238 		case EStateNull:
       
   239 			iCurrentState = EStateClientReqRecvd;
       
   240 			break;
       
   241 			
       
   242 		case EStateClientReqRecvd:
       
   243 			iCurrentState = EStateNetSessStarted;
       
   244 			break;
       
   245 			
       
   246 		case EStateNetSessStarted:
       
   247 			iCurrentState = EStateMeasureDataRecvd;
       
   248 			break;
       
   249 			
       
   250 		case EStateMeasureDataRecvd:
       
   251 			iCurrentState = EStateNetBasedLocSent;
       
   252 			break;
       
   253 			
       
   254 		case EStateNetBasedLocSent:
       
   255 			iCurrentState = EStateLocReqByNet;
       
   256 			iIsMeasureControlHandled = ETrue;
       
   257 			iIsLocReqSentToLbs = ETrue;
       
   258 			break;
       
   259 			
       
   260 		case EStateLocReqByNet:
       
   261 			iCurrentState = EStateLocRespRecvd;
       
   262 			break;
       
   263 			
       
   264 		case EStateLocRespRecvd:
       
   265 			iCurrentState = EStateLocSentToNet;
       
   266 			break;
       
   267 			
       
   268 		case EStateLocSentToNet:
       
   269 			iCurrentState = EStateNetSessToClose;
       
   270 			break;
       
   271 			
       
   272 		case EStateNetSessToClose:
       
   273 			// If a network result is provided then it is sent to LBS
       
   274 			// otherwise the LBS client session closes
       
   275 			iCurrentState = iIsNetResultLocAvailable ? EStateNetResultSent : EStateClientSessToClose;
       
   276 			break;
       
   277 			
       
   278 		case EStateNetResultSent:
       
   279 			iCurrentState = EStateClientSessToClose;
       
   280 			break;
       
   281 
       
   282 		case EStateClientSessToClose:
       
   283 			iCurrentState = EStateSessionsClosed;
       
   284 			break;
       
   285 			
       
   286 		case EStateSessionsClosed:
       
   287 			// Procedure has completed
       
   288 			CompleteProcedure();
       
   289 			break;
       
   290 			
       
   291 		case EStateCancelling:
       
   292 			iCurrentState = EStateNetSessToClose;
       
   293 			break;
       
   294 
       
   295 		default:
       
   296 			User::Panic(KProtocolModulePanic, EProtocolModuleMoLrState);
       
   297 			break;
       
   298 			};
       
   299 		}
       
   300 
       
   301 	}
       
   302 	
       
   303 
       
   304 /** Complete the procedure.
       
   305 */  
       
   306 void CMoLrStateMachine::CompleteProcedure()
       
   307 	{
       
   308 	iCurrentState = EStateNull;
       
   309 	// Complete state machine
       
   310 	CompleteMachineBase();
       
   311 	}
       
   312 
       
   313 
       
   314 /** Complete a state transition.
       
   315 This is called by the base class when a state transition has
       
   316 concluded and it provides an opportunity for the state machine 
       
   317 to perform actions required immediately after this transition.
       
   318 
       
   319 The method can also initiate a further change of state. This is
       
   320 relevant when the state machine is required to perform an autonomous
       
   321 transition from one state to another e.g. this occurs when several
       
   322 interactions are required arising from a single external trigger.
       
   323 */  
       
   324 void CMoLrStateMachine::PostStateTransition()
       
   325 	{
       
   326 	// Some states are transitory i.e. they require
       
   327 	// an automatic transition to the next state
       
   328 	if ( CancelPending() ||
       
   329 		 (EStateClientReqRecvd		== iCurrentState) ||
       
   330 	 	 (EStateMeasureDataRecvd	== iCurrentState) ||
       
   331 	 	 (EStateNetBasedLocSent		== iCurrentState) ||
       
   332 	 	 (EStateLocRespRecvd		== iCurrentState) ||
       
   333 	 	 (EStateNetSessToClose		== iCurrentState) ||
       
   334 	 	 (EStateNetResultSent		== iCurrentState) ||
       
   335 	 	 (EStateClientSessToClose	== iCurrentState) ||
       
   336 	 	 (EStateSessionsClosed		== iCurrentState) ||
       
   337 	 	 (EStateCancelling			== iCurrentState)
       
   338 	   )
       
   339 		{
       
   340 		// Perform a state transition
       
   341 		PerformStateTransition();
       
   342 		}
       
   343 	}
       
   344 
       
   345 
       
   346 /** Do actions required for a queued request.
       
   347 This currently only initiates another state change but it 
       
   348 has the scope for further actions to be carried out according
       
   349 to the nature of a queued request.
       
   350 */
       
   351 void CMoLrStateMachine::DoQueuedRequest(TInt aRequest)
       
   352 	{
       
   353 	switch (aRequest)
       
   354 		{
       
   355 	case EQueueLocResponse:
       
   356 	case EQueueMeasurementControl:
       
   357 	case EQueueNetworkResult:
       
   358 		// Perform a state transition
       
   359 		PerformStateTransition();
       
   360 		break;
       
   361 
       
   362 	default:
       
   363 		User::Panic(KProtocolModulePanic, EProtocolModuleQueueRequestId);
       
   364 		break;
       
   365 		};
       
   366 
       
   367 	}
       
   368 
       
   369 
       
   370 /** Cancel the active procedure
       
   371 */  
       
   372 void CMoLrStateMachine::CancelProcedure()
       
   373 	{
       
   374 	// Kill all timers
       
   375 	iMoLrReqIssuedTimer->Cancel();
       
   376 	iLocRespTimer->Cancel();
       
   377 	iFacResultTimer->Cancel();
       
   378 	iAssistDataTimer->Cancel();
       
   379 	}
       
   380 
       
   381 
       
   382 /** Timer expired callback.
       
   383 This is called by a CStateTimer object when the timer
       
   384 has expired - the event is identified by aEvent parameter.
       
   385 @param aTimerId The timer event identifier.
       
   386 */
       
   387 void CMoLrStateMachine::OnTimerEventL(TInt aTimerId)
       
   388 	{
       
   389 	// Perform relevant action for the expired timer
       
   390 	switch (aTimerId)
       
   391 		{
       
   392 
       
   393 	// MO-LR request timer
       
   394 	case KMoLrReqIssuedTimerEvent:
       
   395 		// Inform protocol manager
       
   396 		Observer().MeasurementControlTimeout();
       
   397 		break;
       
   398 
       
   399 	// Additional assistance data timer
       
   400 	case KAssistDataTimerEvent:
       
   401 		iLocRespReason = KErrTimedOut;
       
   402 		// Inform protocol manager
       
   403 		Observer().MeasurementControlTimeout();
       
   404 		break;
       
   405 
       
   406 	// Facility result timer
       
   407 	case KFacResultTimerEvent:
       
   408 		CancelMachine(ECancelNetworkTimeout);
       
   409 		break;
       
   410 
       
   411 	// Location response timer
       
   412 	case KLocRespTimerEvent:
       
   413 		iLocRespReason = KErrTimedOut;
       
   414 		CancelMachine(ECancelClientTimeout);
       
   415 		break;
       
   416 
       
   417 	// Ignore unknown timer events
       
   418 	default:
       
   419 		break;
       
   420 
       
   421 		};
       
   422 
       
   423 	}
       
   424 
       
   425 
       
   426 /** Timer callback error handler.
       
   427 This is called if the timer expiry callback leaves.
       
   428 @see CMoLrStateMachine::OnTimerEventL()
       
   429 @param aTimerId The timer event identifier.
       
   430 @param aError Error value.
       
   431 */
       
   432 TInt CMoLrStateMachine::OnTimerError(TInt /*aTimerId*/, TInt aError)
       
   433 	{
       
   434 	return aError;
       
   435 	}
       
   436 
       
   437 
       
   438 /** Handle Measurement Control timeout
       
   439 */
       
   440 void CMoLrStateMachine::MeasurementControlTimeout()
       
   441 	{
       
   442 	// Ensure assistance data action is performed upon cancellation
       
   443 	iAssistanceDataActionRequired = ETrue;
       
   444 
       
   445 	// Cancel procedure
       
   446 	CancelMachine(ECancelNetworkTimeout);
       
   447 	}
       
   448 
       
   449 
       
   450 /** Handle LBS request for MO-LR
       
   451 @param aSessionId The session ID supplied by LBS.
       
   452 */
       
   453 void CMoLrStateMachine::MoLrReq(const TLbsNetSessionId& aSessionId)
       
   454 	{
       
   455 	// Store the supplied ID information
       
   456 	SessionId(aSessionId);
       
   457 
       
   458 	// Initialise the new procedure
       
   459 	InitialiseProcedure();
       
   460 
       
   461 	// This state machine requires assistance data actions
       
   462 	// to be performed immediately immediate
       
   463 	iObserver.DoAssistanceDataActions();
       
   464 
       
   465 	// Perform a state transition
       
   466 	PerformStateTransition();
       
   467 	}
       
   468 
       
   469 
       
   470 /** Queue an LBS request for MO-LR
       
   471 @param aSessionId The session ID supplied by LBS.
       
   472 */
       
   473 void CMoLrStateMachine::QueueMoLrReq(const TLbsNetSessionId& aSessionId)
       
   474 	{
       
   475 	// Store the session ID
       
   476 	QueueSessionId(aSessionId);
       
   477 
       
   478 	CStateMachineBase::SetMachineAsQueued();
       
   479 	}
       
   480 	
       
   481 
       
   482 /** Start previously queued state machine.
       
   483 */  
       
   484 void CMoLrStateMachine::StartQueuedMachine()
       
   485 	{
       
   486 	MoLrReq(iQueueSessionId);
       
   487 	}
       
   488 
       
   489 
       
   490 /** Handle LBS Location response
       
   491 @param aReason Location response error reason.
       
   492 @param aPosInfo The location information response from LBS.
       
   493 */
       
   494 void CMoLrStateMachine::LocationResp(TInt aReason, const TPositionInfoBase& aPosInfo)
       
   495 	{
       
   496 	// Store location response data
       
   497 	StoreLocationResp(aReason, aPosInfo);
       
   498 
       
   499 	// Kill the timer related to location response expected by network
       
   500 	iLocRespTimer->Cancel();
       
   501 
       
   502 	// Is the state machine inactive?
       
   503 	if (!IsActive())
       
   504 		{
       
   505 		// Perform a state transition
       
   506 		PerformStateTransition();
       
   507 		}
       
   508 	else
       
   509 		{
       
   510 		// Queue the request
       
   511 		iQueue->AddRequest(EQueueLocResponse);
       
   512 		}
       
   513 	}
       
   514 
       
   515 
       
   516 /** Handle Network Measurement Control indication.
       
   517 A measurement control indication has been received from the network.
       
   518 Note: At this stage the assistance data has already been stored by the
       
   519 protocol manager and is thus not passed into this method.
       
   520 
       
   521 @param aPosInfo Reference location information provided in the measurement control
       
   522 @param aQuality Location request quality specified in the measuerment control
       
   523 */
       
   524 void CMoLrStateMachine::MeasurementControlInd(const TPositionInfoBase& aPosInfo,
       
   525 	const TLbsNetPosRequestQuality& aQuality, const TLbsNetPosRequestMethod& aPosMethod)
       
   526 	{
       
   527 	// Kill timer related to the MO-LR request
       
   528 	iMoLrReqIssuedTimer->Cancel();
       
   529 
       
   530 	// Perform base class actions
       
   531 	CStateMachineBase::MeasurementControlInd(aPosInfo, aQuality, aPosMethod);
       
   532 
       
   533 	// Is the state machine inactive?
       
   534 	if (!IsActive())
       
   535 		{
       
   536 		// Perform a state transition
       
   537 		PerformStateTransition();
       
   538 		}
       
   539 	else
       
   540 		{
       
   541 		// Queue the request
       
   542 		iQueue->AddRequest(EQueueMeasurementControl);
       
   543 		}
       
   544 	}
       
   545 
       
   546 
       
   547 /** Handle Network Measurement Control Error indication
       
   548 This is called by the protocol manager durinq an active MO-LR when
       
   549 a measurement control error is received from the network.
       
   550 */
       
   551 void CMoLrStateMachine::MeasurementControlErrorInd(TInt aReason)
       
   552 	{
       
   553 	TBool cancelRequired = EFalse;
       
   554 	TBool assistActionRequired = ETrue;
       
   555 
       
   556 	// If there is no outstanding assistance data request then 
       
   557 	// inhibit assistance data error responses.
       
   558 	if (!iMoLrReqIssuedTimer->IsActive() && 
       
   559 		!iAssistDataTimer->IsActive())
       
   560 		{
       
   561 		assistActionRequired = EFalse;
       
   562 		}
       
   563 
       
   564 	// Is this the first measurement control received?
       
   565 	if (!IsLocReqReceived() || (KErrCancel == aReason))
       
   566 		{
       
   567 		// Kill timer related to the MO-LR request
       
   568 		iMoLrReqIssuedTimer->Cancel();
       
   569 		cancelRequired = ETrue;
       
   570 		}
       
   571 
       
   572 	// Perform base class actions
       
   573 	CStateMachineBase::HandleMeasureControlError(cancelRequired, aReason);
       
   574 
       
   575 	// Ensure assistance data action only happens if necessary
       
   576 	iAssistanceDataActionRequired = assistActionRequired;
       
   577 	}
       
   578 
       
   579 
       
   580 /** Handle Network Session Result
       
   581 @param aResult The error result from network session closure.
       
   582 @param aPosInfo A pointer to final result location information from the network.
       
   583 	This can be null if there is not final position provided.
       
   584 */
       
   585 void CMoLrStateMachine::SessionResult(TInt aResult, const TPositionInfoBase* aPosInfo)
       
   586 	{
       
   587 	// Kill timer related to the facility result
       
   588 	iFacResultTimer->Cancel();
       
   589 
       
   590 	iNetSessionResult = aResult;
       
   591 
       
   592 	// Is a position provided?
       
   593 	if (aPosInfo)
       
   594 		{
       
   595 		// Store network resulting location
       
   596 		StoreNetResultLoc(*aPosInfo);
       
   597 		iIsNetResultLocAvailable = ETrue;
       
   598 		}
       
   599 	else
       
   600 		{
       
   601 		iIsNetResultLocAvailable = EFalse;
       
   602 		}
       
   603 
       
   604 	// Is state machine inactive?
       
   605 	if (!IsActive())
       
   606 		{
       
   607 		// Perform a state transition
       
   608 		PerformStateTransition();
       
   609 		}
       
   610 	else
       
   611 		{
       
   612 		// Queue request
       
   613 		iQueue->AddRequest(EQueueNetworkResult);
       
   614 		}
       
   615 	}
       
   616 
       
   617 
       
   618 /** Handle a network error indication.
       
   619 */  
       
   620 void CMoLrStateMachine::NetworkErrorInd()
       
   621 	{
       
   622 	// Do we need to report assistance data errors?
       
   623 	if (!IsLocReqReceived())
       
   624 		{
       
   625 		iAssistanceDataActionRequired = ETrue;
       
   626 		}
       
   627 
       
   628 	// Perform base class actions
       
   629 	CStateMachineBase::NetworkErrorInd();
       
   630 	}
       
   631