diff -r 000000000000 -r 9cfd9a3ee49c networkprotocolmodules/networkprotocolmodule/LbsProtocolModule/src/cprotocolmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkprotocolmodules/networkprotocolmodule/LbsProtocolModule/src/cprotocolmanager.cpp Tue Feb 02 01:50:39 2010 +0200 @@ -0,0 +1,1083 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// This file provides the implementation of the class that manages +// protocol aspects of Test Protocol Module operation. +// +// + +/** + @file + @internalTechnology + @released +*/ + +#include +#include +#include "cconfigmanager.h" +#include "cmolrstatemachine.h" +#include "cmtlrstatemachine.h" +#include "cx3pstatemachine.h" +#include "cnetlocstatemachine.h" +#include "cprotocolmanager.h" +#include "cassistdatamgr.h" +#include "lbsdevloggermacros.h" + +#ifdef ENABLE_LBS_DEV_LOGGER +#include +#endif + +/** The unique ID of this plug-in implementation. +This corresponds to the implementation UID specified in the .rss file +for this protocol module. +*/ +const TInt KPluginUidValue = 0x10281D70; +const TUid KPluginUid = { KPluginUidValue }; + + +/** Static constructor. +@param aGateway A reference to the protocol manager observer +@return A new instance of the CProtocolManager class +*/ +CProtocolManager* CProtocolManager::NewL(MProtocolMgrObserver& aGateway) + { + CProtocolManager* self = new (ELeave) CProtocolManager(aGateway); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +/** Standard constructor. +@param aGateway A reference to the protocol manager observer +*/ +CProtocolManager::CProtocolManager(MProtocolMgrObserver& aGateway) +: iGateway(aGateway), iLbsStatus(CLbsNetworkProtocolBase::ESystemStatusNone), + iActiveServiceMask(MLbsNetworkProtocolObserver::EServiceNone) + { + iInternalSessionId.SetSessionOwner(KPluginUid); + iInternalSessionId.SetSessionNum(0); + + LBSLOG(ELogP2, "CProtocolManager::CProtocolManager() CurrentOp --> EOpNone\n"); + iCurrentOp.iOperation = CConfigManager::EOpNone; + iCurrentOp.iPriority = CConfigManager::EPriorityNone; + } + + +/** Standard destructor. +*/ +CProtocolManager::~CProtocolManager() + { + delete iAssistMgr; + delete iNetLoc; + delete iX3p; + delete iMtLr; + delete iMoLr; + delete iConfig; + delete iNetwork; + } + + +/** Private second-stage constructor. +*/ +void CProtocolManager::ConstructL() + { + iNetwork = CNetworkInterface::NewL(*this); + iNetwork->Connect(); + + iConfig = CConfigManager::NewL(); + iMoLr = CMoLrStateMachine::NewL(*this); + iMtLr = CMtLrStateMachine::NewL(*this); + iX3p = CX3pStateMachine::NewL(*this); + iNetLoc = CNetLocStateMachine::NewL(*this); + iAssistMgr = CAssistDataMgr::NewL(); + } + + +/** Identify active state machine +@param aActiveMachine A reference to a pointer that identifies the active + state machine. This pointer is set to NULL if there is no active machine. +*/ +void CProtocolManager::GetActiveStateMachine(CStateMachineBase*& aActiveMachine) const + { + //LBSLOG(ELogP2, "CProtocolManager::GetActiveStateMachine() \n"); + if (CStateMachineBase::EStateActive == iMtLr->State()) + { + LBSLOG(ELogP2, "CProtocolManager::GetActiveStateMachine() Active Machine = MTLR\n"); + aActiveMachine = iMtLr; + } + else if (CStateMachineBase::EStateActive == iMoLr->State()) + { + LBSLOG(ELogP2, "CProtocolManager::GetActiveStateMachine() Active Machine = MOLR\n"); + aActiveMachine = iMoLr; + } + else if (CStateMachineBase::EStateActive == iX3p->State()) + { + LBSLOG(ELogP2, "CProtocolManager::GetActiveStateMachine() Active Machine = X3P\n"); + aActiveMachine = iX3p; + } + else if (CStateMachineBase::EStateActive == iNetLoc->State()) + { + LBSLOG(ELogP2, "CProtocolManager::GetActiveStateMachine() Active Machine = NBLR\n"); + aActiveMachine = iNetLoc; + } + else + { + LBSLOG(ELogP2, "CProtocolManager::GetActiveStateMachine() No Active Machine\n"); + aActiveMachine = NULL; + } + + } + + +/** Identify a state machine that is currently cancelling. +@param aCancellingMachine A reference to a pointer that identifies the cancelling + state machine. This pointer is set to NULL if there is no cancelling machine. +*/ +void CProtocolManager::GetCancellingStateMachine(CStateMachineBase*& aCancellingMachine) const + { + + if (CStateMachineBase::EStateCancelling == iMtLr->State()) + { + aCancellingMachine = iMtLr; + } + else if (CStateMachineBase::EStateCancelling == iMoLr->State()) + { + aCancellingMachine = iMoLr; + } + else if (CStateMachineBase::EStateCancelling == iX3p->State()) + { + aCancellingMachine = iX3p; + } + else if (CStateMachineBase::EStateCancelling == iNetLoc->State()) + { + aCancellingMachine = iNetLoc; + } + else + { + aCancellingMachine = NULL; + } + } + + +/** Identify a state machine that is currently queued. +This will identify a state machine that is queued and ready to be started. +Priority is given to MT-LR because whilst another machine is cancelling +an MT-LR emergency request may be briefly queued. + +@param aQueuedMachine A reference to a pointer that identifies a queued + state machine. This pointer is set to NULL if there is no queued machine. +*/ +void CProtocolManager::GetQueuedStateMachine(CStateMachineBase*& aQueuedMachine) const + { + if (iMtLr->IsMachineQueued()) + { + aQueuedMachine = iMtLr; + } + else if (iMoLr->IsMachineQueued()) + { + aQueuedMachine = iMoLr; + } + else if (iX3p->IsMachineQueued()) + { + aQueuedMachine = iX3p; + } + else if (iNetLoc->IsMachineQueued()) + { + aQueuedMachine = iNetLoc; + } + else + { + aQueuedMachine = NULL; + } + + } + + +/** Resolve the conflict between an active procedure and a new request. +@param aNewOp The type of operation that is represented by the new request. +@param aNewPriority The priority of the new request - optional. +@return TBool An indication if the +*/ +CConfigManager::TConflictResult CProtocolManager::ResolveConflict( + CConfigManager::TConflictOp aNewOp, + CConfigManager::TConflictPriority aNewPriority) + { + CConfigManager::TConflictResult conflictResult = CConfigManager::EConflictNone; + CStateMachineBase* activeMachine; + CStateMachineBase* cancellingMachine; + GetActiveStateMachine(activeMachine); + GetCancellingStateMachine(cancellingMachine); + + LBSLOG3(ELogP2, "CProtocolManager::ResolveConflict() Current op = %d, New op = %d\n", iCurrentOp.iOperation, aNewOp); + + // One special case relates to an existing MT-LR that is awaiting the + // measurement control after a privacy reject. This MT-LR sequence can be + // cancelled once a new request arrives. + if ((iMtLr == activeMachine) && (iMtLr->IsRejectedWaitingMeasureControl())) + { + iMtLr->CancelMachine(CStateMachineBase::ECancelNone); + conflictResult = CConfigManager::EConflictCancelCurrent; + } + // There is an operation already in the process of being cancelled, + // so queue the new request until this completes. + else if (NULL != cancellingMachine) + { + LBSLOG(ELogP2, "CProtocolManager::ResolveConflict() Queing new request while previous op cancelled\n"); + conflictResult = CConfigManager::EConflictQueueNew; + } + else + { + CConfigManager::TConflictOperation newOp; + newOp.iOperation = aNewOp; + newOp.iPriority = aNewPriority; + + // A special case is when tracking is set on and it is not a new MO-LR request. + // If there is not a current active operation, or MOLR is active, then + // there may be a need to cancel a tracking 'session'. + if ((iLbsStatus & CLbsNetworkProtocolBase::ESystemStatusClientTracking) && + (CConfigManager::EOpMoLr != aNewOp) && + ((NULL == activeMachine) || (iMoLr == activeMachine))) + { + // Use a fake MO-LR to obtain a conflict decision. + CConfigManager::TConflictOperation fakeMoLrOp; + fakeMoLrOp.iOperation = CConfigManager::EOpMoLr; + fakeMoLrOp.iPriority = CConfigManager::EPriorityNone; + conflictResult = iConfig->ConflictDecision(fakeMoLrOp, newOp); + + // Should tracking be cancelled? + if ((CConfigManager::EConflictCancelCurrent == conflictResult) || + (CConfigManager::EConflictQueueCurrent == conflictResult)) + { + // Turn tracking off + iLbsStatus = CLbsNetworkProtocolBase::ESystemStatusNone; + if (NULL == activeMachine) + { + // Cancel tracking session if we have no active operation and + // there has been a preceding MOLR session + if ((iMoLr->SessionId().SessionOwner().iUid != 0) || + (iMoLr->SessionId().SessionNum() != 0)) + { + Gateway()->SessionCompleteInd(iMoLr->SessionId(), KErrPositionHighPriorityReceive); + } + conflictResult = CConfigManager::EConflictNone; + } + } + } + // If we have an active operation which needs a conflict decision + else if( (NULL != activeMachine) /*&& (iCurrentOp.iOperation != CConfigManager::EOpNone)*/) + { + conflictResult = iConfig->ConflictDecision(iCurrentOp, newOp); + } + else + { + // no tracking and no active operation = no conflict + } + + // Perform any initial action arising from conflict decision + switch (conflictResult) + { + // Current operation must be cancelled + case CConfigManager::EConflictCancelCurrent: + // Indicate if the source of cancellation is the network or LBS + if ((CConfigManager::EOpMtLr == aNewOp) || + (CConfigManager::EOpNiLr == aNewOp)) + { + LBSLOG(ELogP2, "CProtocolManager::ResolveConflict() Cancelling state machine, client\n"); + activeMachine->CancelMachine(CStateMachineBase::ECancelNetworkCancel, KErrPositionHighPriorityReceive); + } + else + { + LBSLOG(ELogP2, "CProtocolManager::ResolveConflict() Cancelling state machine, network\n"); + activeMachine->CancelMachine(CStateMachineBase::ECancelClientCancel, KErrPositionHighPriorityReceive); + } + break; + + // Queue the current operation before performing new operation + // Note: At present we only have a requirement to queue an X3P timer + // and the functionality to support this is as follows: + // (a) cancel current operation BUT without cancelling LBS session + // (b) silently consume any LBS responses that relate to this session + // (c) proceed with the new operation + // (d) wait for LBS (NRH) to repeat the X3P timer request + case CConfigManager::EConflictQueueCurrent: + activeMachine->CancelMachine(CStateMachineBase::ECancelClientCancelSilent, KErrPositionHighPriorityReceive); + break; + + // Other conflict results require no further action here + default: + break; + }; + } + + LBSLOG2(ELogP2, "CProtocolManager::ResolveConflict() returning conflict result %d\n", conflictResult); + return conflictResult; + } + + +/** Handle LBS request for Assistance Data +@param aDataRequestMask A mask identifying the set of data requested. +*/ +void CProtocolManager::AssistanceDataReq(TLbsAsistanceDataGroup aDataRequestMask) + { + // Pass request to the assistance data manager to process + TBool noAssistanceNeeded = iAssistMgr->ProcessDataRequest(aDataRequestMask); + + // No assistance needed? + if (noAssistanceNeeded) + { + // Do nothing! + } + // Check if the requested data mask was entirely invalid + else if (iAssistMgr->RequestErrorMask() == aDataRequestMask) + { + // Report the request error now + DoAssistanceDataActions(); + } + else + { + // Check if we have an active state machine + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + if (NULL != activeMachine) + { + // Advise state machine of assistance data request + activeMachine->AssistanceDataReq(); + } + else + { + // Store assistance data error + iAssistMgr->Error(KErrGeneral); + + // Report the error + DoAssistanceDataActions(); + } + } + } + + +/** Handle LBS request for self locate +@param aSessionId The session ID supplied by LBS. +@param aDataRequestMask A mask identifying the set of data requested. +*/ +void CProtocolManager::SelfLocationReq(const TLbsNetSessionId& aSessionId, + const TLbsNetPosRequestOptionsBase& aOptions) + { + + LBSLOG(ELogP2, "CProtocolManager::SelfLocationReq()\n"); + const TLbsNetPosRequestOptionsAssistance options = reinterpret_cast (aOptions); + // Pass assistance data mask to the assistance data manager to process + TBool noAssistanceNeeded = iAssistMgr->ProcessDataRequest(options.DataRequestMask()); + + // Was assistance data request entirely invalid + if (iAssistMgr->RequestErrorMask() == options.DataRequestMask() && + !noAssistanceNeeded) + { + // Ensure this error is reported + DoAssistanceDataActions(); + noAssistanceNeeded = ETrue; + } + + // Is there already an MO-LR active? + if (CStateMachineBase::EStateActive == iMoLr->State()) + { + LBSLOG(ELogP2, "CProtocolManager::SelfLocationReq() Previously we would've ignored this request!!!!!!\n"); + } + + CConfigManager::TConflictResult conflictResult = ResolveConflict(CConfigManager::EOpMoLr); + // Resolve any conflicts arising + switch (conflictResult) + { + // Start MO-LR + case CConfigManager::EConflictNone: + LBSLOG(ELogP2, "CProtocolManager::SelfLocationReq() No conflict\n"); + // Network interaction is not required under these circumstances: + // (a) GPS mode is autonomous OR + // (b) this is an old client AND no assistance data was requested + if (TPositionModuleInfo::ETechnologyTerminal == options.PosMode() || + (!options.NewClientConnected() && noAssistanceNeeded)) + { + // End the LBS session + LBSLOG(ELogP2, "CProtocolManager::SelfLocationReq() Ending session due to autonomous OR old client not requiring ass data\n"); + Gateway()->SessionCompleteInd(aSessionId, KErrNone); + } + else + { + // Status update sent to LBS + StatusUpdate(CConfigManager::EOpMoLr, ETrue); // ETrue=new operation + // Need to set the assistance data manager as if no data + // has been received yet, and all previous data has been reported, + // to ensure that any existing set of data is reported to LBS. + iAssistMgr->DataReported(); + iAssistMgr->SetDataNotReceived(); + iMoLr->MoLrReq(aSessionId); + LBSLOG(ELogP2, "CProtocolManager::SelfLocationReq() CurrentOp --> EOpMoLr\n"); + iCurrentOp.iOperation = CConfigManager::EOpMoLr; + iCurrentOp.iPriority = CConfigManager::EPriorityNone; + } + break; + + // Reject the new request + case CConfigManager::EConflictRejectNew: + LBSLOG(ELogP2, "CProtocolManager::SelfLocationReq() Conflict: Rejecting new request\n"); + Gateway()->SessionCompleteInd(aSessionId, KErrServerBusy); + break; + + // New request is queued whilst current operation continues + // or current operation is being cancelled. + case CConfigManager::EConflictQueueNew: + case CConfigManager::EConflictCancelCurrent: + case CConfigManager::EConflictQueueCurrent: + LBSLOG2(ELogP2, "CProtocolManager::SelfLocationReq() Conflict %d: Queueing new request\n", conflictResult); + iMoLr->QueueMoLrReq(aSessionId); + break; + + default: + break; + }; + } + + +/** Handle LBS completion of self locate +@param aSessionId The session to be completed. +@param aReason Completion reason value. +*/ +void CProtocolManager::SelfLocationCompleteInd(const TLbsNetSessionId& aSessionId, + TInt aReason) + { + // Check we have an active self locate and valid session ID, + // otherwise silently consume this completion indication. + if ((CStateMachineBase::EStateActive == iMoLr->State()) && + (aSessionId == iMoLr->SessionId())) + { + iMoLr->CancelMachine(CStateMachineBase::ECancelClientCancel, aReason); + } + } + + +/** Handle LBS system status indication +@param aStatus The status indication from LBS. +*/ +void CProtocolManager::SystemStatusInd(CLbsNetworkProtocolBase::TLbsSystemStatus aStatus) + { + iLbsStatus = aStatus; + } + + +/** Handle LBS Location Response +@param aSessionId The session ID for which this response is provided. +@param aReason An error response; KErrNone if position is okay. +@param aPosInfo The location response information +*/ +void CProtocolManager::LocationResp(const TLbsNetSessionId& aSessionId, TInt aReason, const TPositionInfoBase& aPosInfo) + { + // Check we have an active state machine to handle this + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + + // Special requirement to allow MT-LR to receive late responses + if ((NULL == activeMachine) && + (CStateMachineBase::EStateCancelling == iMtLr->State())) + { + activeMachine = iMtLr; + } + + // Check there is an active state machine and that session ID is legitimate, + // otherwise silently consume this location response. + if ((NULL != activeMachine) && (aSessionId == activeMachine->SessionId())) + { + activeMachine->LocationResp(aReason, aPosInfo); + } + + } + + +/** Handle LBS Privacy Response +@param aResponse Privacy response value. +*/ +void CProtocolManager::PrivacyResp(const TLbsNetSessionId& aSessionId, + const CLbsNetworkProtocolBase::TLbsPrivacyResponse& aResponse) + { + // Check we have an active MT-LR state machine and valid session ID, + // otherwise silently consume this privacy response. + if ((CStateMachineBase::EStateActive == iMtLr->State()) && + (aSessionId == iMtLr->SessionId())) + { + iMtLr->PrivacyResp(aResponse); + } + } + + +/** Handle LBS Network Based Location Request +*/ +void CProtocolManager::NetworkBasedLocationReq(const TLbsNetSessionId& aSessionId, + const TLbsNetPosRequestOptionsBase& /*aOptions*/) + { + LBSLOG2(ELogP2, "CProtocolManager::NetworkBasedLocationReq() session id %d\n", aSessionId.SessionNum()); + // Resolve any conflicts arising + switch (ResolveConflict(CConfigManager::EOpNbLr)) + { + // Start Network Based Location + case CConfigManager::EConflictNone: + // Status update sent to LBS + StatusUpdate(CConfigManager::EOpNbLr, ETrue); // ETrue=new operation + iNetLoc->NetLocReq(aSessionId); + LBSLOG(ELogP2, "CProtocolManager::NetworkBasedLocationReq() CurrentOp --> EOpNbLr\n"); + iCurrentOp.iOperation = CConfigManager::EOpNbLr; + iCurrentOp.iPriority = CConfigManager::EPriorityNone; + break; + + // Reject the new request + case CConfigManager::EConflictRejectNew: + Gateway()->SessionCompleteInd(aSessionId, KErrServerBusy); + break; + + // New request is queued whilst current operation continues + // or current operation is being cancelled. + case CConfigManager::EConflictQueueNew: + case CConfigManager::EConflictCancelCurrent: + case CConfigManager::EConflictQueueCurrent: + LBSLOG2(ELogP2, "CProtocolManager::NetworkBasedLocationReq() Queueing NetLocrequest with session id %d\n", aSessionId.SessionNum()); + iNetLoc->QueueNetLocReq(aSessionId); + break; + + default: + break; + }; + } + + +/** Handle LBS Completion of a Network Based Location Request +*/ +void CProtocolManager::NetworkBasedLocationCompleteInd(const TLbsNetSessionId& aSessionId, + TInt aReason) + { + LBSLOG2(ELogP2, "CProtocolManager::NetworkBasedLocationCompleteInd() session id %d\n", aSessionId.SessionNum()); + // Check we have an active Network Based Loc state machine and valid session ID, + // otherwise silently consume this completion indication. + if ((CStateMachineBase::EStateActive == iNetLoc->State()) && + (aSessionId == iNetLoc->SessionId())) + { + iNetLoc->CancelMachine(CStateMachineBase::ECancelClientCancel, aReason); + } + } + + +/** Handle LBS Transmit Location Request +*/ +void CProtocolManager::TransmitLocationReq(const TLbsNetSessionId& aSessionId, const TDesC& aDest, TInt aPriority) + { + CConfigManager::TConflictPriority priority; + switch(aPriority) + { + case 0x10: // Timer + priority = CConfigManager::EPriorityLow; + break; + + case 0x08: // Menu + priority = CConfigManager::EPriorityMedium; + break; + + case 0x02: // Push + priority = CConfigManager::EPriorityHigh; + break; + + default: + priority = CConfigManager::EPriorityNone; + break; + }; + + // Resolve any conflicts arising + switch (ResolveConflict(CConfigManager::EOpX3p, priority)) + { + // Start X3P + case CConfigManager::EConflictNone: + // Status update sent to LBS + StatusUpdate(CConfigManager::EOpX3p, ETrue); // ETrue=new operation + iX3p->X3pReq(aSessionId, aDest); + LBSLOG(ELogP2, "CProtocolManager::TransmitLocationReq() CurrentOp --> EOpX3p\n"); + iCurrentOp.iOperation = CConfigManager::EOpX3p; + iCurrentOp.iPriority = priority; + break; + + // Reject the new request + case CConfigManager::EConflictRejectNew: + Gateway()->SessionCompleteInd(aSessionId, KErrServerBusy); + break; + + // New request is queued whilst current operation continues + // or current operation is being cancelled. + case CConfigManager::EConflictQueueNew: + case CConfigManager::EConflictCancelCurrent: + case CConfigManager::EConflictQueueCurrent: + iX3p->QueueX3pReq(aSessionId, aDest); + break; + + default: + break; + }; + } + + +/** Handle LBS Completion of a Transmit Location Request +*/ +void CProtocolManager::TransmitLocationCompleteInd(const TLbsNetSessionId& aSessionId, TInt aReason) + { + // Check we have an active X3P state machine and valid session ID, + // otherwise silently consume this completion indication + if ((CStateMachineBase::EStateActive == iX3p->State()) && + (aSessionId == iX3p->SessionId())) + { + // Cancel + iX3p->CancelMachine(CStateMachineBase::ECancelClientCancel, aReason); + } + } + + +// +// MNetworkObserver methods +// + + +/** Get a new session ID +@see MNetworkObserver::NewSession() +*/ +const TLbsNetSessionId& CProtocolManager::NewSessionId() + { + iInternalSessionId.IncrSession(); + return iInternalSessionId; + } + + +/** Handle Network Measurement Control indication +@see MNetworkObserver +*/ +void CProtocolManager::MeasurementControlInd(const TPositionInfoBase& aPosInfo, + const RLbsAssistanceDataBuilderSet& aData, const TLbsNetPosRequestQuality& aQuality, + const TLbsNetPosRequestMethod& aPosMethod) + { + LBSLOG(ELogP2, "CProtocolManager::MeasurementControlInd()\n"); + // Store assistance data + iAssistMgr->StoreData(aData); + + // Check if we have an active state machine to handle this + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + CStateMachineBase* cancellingMachine; + GetCancellingStateMachine(cancellingMachine); + if (NULL != activeMachine) + { + // Is this the first measurement control received? + if (!activeMachine->IsLocReqReceived()) + { + // Forward the measurement and control to the state machine + activeMachine->MeasurementControlInd(aPosInfo, aQuality, aPosMethod); + } + else + { + // Advise state machine of pending assistance data + activeMachine->AdditionalAssistDataInd(); + } + } + // Any cancelling state machine? + else if (NULL != cancellingMachine) + { + // Forward the measurement and control to the state machine + cancellingMachine->MeasurementControlInd(aPosInfo, aQuality, aPosMethod); + } + else + { + // If there is no active or cancelling operation then this can be + // interpreted as a network induced location request (NI-LR). + + // We must perform conflict decision-making before handling this + CConfigManager::TConflictPriority priority; + priority = (iMtLr->IsEmergency()) ? CConfigManager::EPriorityEmergency : CConfigManager::EPriorityNone; + switch (ResolveConflict(CConfigManager::EOpNiLr, priority)) + { + // Start NI-LR + case CConfigManager::EConflictNone: + { + // Status update sent to LBS + StatusUpdate(CConfigManager::EOpNiLr, ETrue); // ETrue=new operation + // The NI-LR requires a new session + iMtLr->SessionId(NewSessionId()); + LBSLOG(ELogP2, "CProtocolManager::MeasurementControlInd() CurrentOp --> EOpNiLr\n"); + iCurrentOp.iOperation = CConfigManager::EOpNiLr; + iCurrentOp.iPriority = priority; + + // Forward the measurement and control to the MT-LR state machine + iMtLr->MeasurementControlInd(aPosInfo, aQuality, aPosMethod); + } + break; + + // Reject the new request + case CConfigManager::EConflictRejectNew: + { + CNetworkInterface::TNetworkError netError = + Network()->LocationResp(KErrServerBusy); + // Handle network-related error + if (CNetworkInterface::ENone != netError) + { + NetworkErrorReported(); + } + } + break; + + // We don't do anything for other conflict responses because we + // could only be in the process of cancelling an active operation + // for which this measurement control becomes redundant. + default: + break; + }; + } + } + + +/** Handle Network Measurement Control error indication +@see MNetworkObserver +*/ +void CProtocolManager::MeasurementControlErrorInd(TInt aReason) + { + LBSLOG2(ELogP2, "CProtocolManager::NetworkErrorInd(%d)\n", aReason); + // Store assistance data error + iAssistMgr->Error(aReason); + + // Check if we have an active state machine to handle this, + // otherwise silently consume this error indication. + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + if (NULL != activeMachine) + { + // Advise state machine of error + activeMachine->MeasurementControlErrorInd(aReason); + } + } + + +/** Handle Network MT-LR request +@see MNetworkObserver +*/ +void CProtocolManager::MtLrReq(const TLbsExternalRequestInfo& aReqInfo, + const TLbsNetPosRequestPrivacy& aPrivacy) + { + // Resolve any conflicts arising + CConfigManager::TConflictPriority priority; + priority = (iMtLr->IsEmergency()) ? CConfigManager::EPriorityEmergency : CConfigManager::EPriorityNone; + switch (ResolveConflict(CConfigManager::EOpMtLr, priority)) + { + // Start MT-LR + case CConfigManager::EConflictNone: + // Status update sent to LBS + StatusUpdate(CConfigManager::EOpMtLr, ETrue); // ETrue=new operation + iMtLr->MtLrReq(aReqInfo, aPrivacy); + LBSLOG(ELogP2, "CProtocolManager::MtLrReq() CurrentOp --> EOpMtLr\n"); + iCurrentOp.iOperation = CConfigManager::EOpMtLr; + iCurrentOp.iPriority = priority; + break; + + // Reject the new request + case CConfigManager::EConflictRejectNew: + Network()->MtLrResp(CLbsNetworkProtocolBase::EPrivacyResponseRejected); + break; + + // New request is queued whilst current operation continues + // or current operation is being cancelled. + case CConfigManager::EConflictQueueNew: + case CConfigManager::EConflictCancelCurrent: + case CConfigManager::EConflictQueueCurrent: + iMtLr->QueueMtLrReq(aReqInfo, aPrivacy); + break; + + default: + break; + }; + } + + +/** Handle Network MT-LR cancel indication +@see MNetworkObserver +*/ +void CProtocolManager::MtLrCancelInd(TInt aReason) + { + // If we have an active state machine then forward the indication, + // otherwise silently consume this cancel indication. + if (CStateMachineBase::EStateActive == iMtLr->State()) + { + iMtLr->MtLrCancelInd(aReason); + } + } + + +/** Handle Network session result indication +@see MNetworkObserver +*/ +void CProtocolManager::NetworkResultInd(TInt aResult, const TPositionInfoBase* aPosInfo) + { + LBSLOG2(ELogP2, "CProtocolManager::NetworkErrorInd() Result = %d\n", aResult); + // Check we have an active state machine to handle this, + // otherwise silently consume this indication. + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + + if (NULL != activeMachine) + { + // Pass the indication on to the active state machine + if (CStateMachineBase::EStateActive == iMoLr->State()) + { + iMoLr->SessionResult(aResult, aPosInfo); + } + + if (CStateMachineBase::EStateActive == iX3p->State()) + { + iX3p->SessionResult(aResult, aPosInfo); + } + } + } + + +/** Handle Network error indication +@see MNetworkObserver +*/ +void CProtocolManager::NetworkErrorInd(TInt aReason) + { + LBSLOG2(ELogP2, "CProtocolManager::NetworkErrorInd(%d)\n", aReason); + // Ensure any active state machine is informed of this problem + CStateMachineBase* stateMachine; + GetActiveStateMachine(stateMachine); + if (NULL != stateMachine) + { + // Advise state machine of error + stateMachine->NetworkErrorInd(); + + // Store assistance data error. This is only reported if the + // state machine indicates that assistance data actions should + // be performed. + if (stateMachine->IsAssistanceDataActionReq()) + { + iAssistMgr->Error(aReason); + } + } + } + + +/** Network request for LBS capabilities +@see MNetworkObserver +*/ +void CProtocolManager::GetCapabilities(TLbsNetPosCapabilities& aCapabilities) + { + Gateway()->GetCapabilities(aCapabilities); + } + +/** Network request for reseting of assistance data +@see MNetworkObserver +*/ +void CProtocolManager::ResetAssistanceData(TLbsAssistanceDataGroup aMask) + { + iAssistMgr->ResetData(); + Gateway()->ResetAssistanceData(aMask, iAssistMgr->ValidData()); + } + +// MStateMachineObserver methods + +/** Gateway interface pointer. +@see MStateMachineObserver +*/ +MProtocolMgrObserver* CProtocolManager::Gateway() + { + return &iGateway; + } + + +/** Network interface pointer. +@see MStateMachineObserver +*/ +CNetworkInterface* CProtocolManager::Network() + { + return iNetwork; + } + + +/** State machine procedure complete notification +@see MStateMachineObserver +*/ +void CProtocolManager::ProcedureCompleteInd() + { + LBSLOG(ELogP2, "CProtocolManager::ProcedureCompleteInd() CurrentOp --> None\n"); + // Status update sent to LBS + StatusUpdate(iCurrentOp.iOperation, EFalse); // EFalse=operation ended + + iCurrentOp.iOperation = CConfigManager::EOpNone; + iCurrentOp.iPriority = CConfigManager::EPriorityNone; + + // Identify if any request was queued and if this is the case + // start the relevant state machine. + CStateMachineBase* queuedMachine; + GetQueuedStateMachine(queuedMachine); + if (NULL != queuedMachine) + { + // Set the current operation appropriately: + if(queuedMachine == iMtLr) + { + iCurrentOp.iOperation = CConfigManager::EOpMtLr; + } + else if(queuedMachine == iMoLr) + { + iCurrentOp.iOperation = CConfigManager::EOpMoLr; + } + else if(queuedMachine == iX3p) + { + // TO DO - how do we know what priority to use here!? + iCurrentOp.iOperation = CConfigManager::EOpX3p; + } + else + { + ASSERT(queuedMachine == iNetLoc); + iCurrentOp.iOperation = CConfigManager::EOpNbLr; + } + + // Set Current Operation appropriately: + queuedMachine->StartQueuedMachine(); + } + } + + +/** Handle Measurement Control timeout +@see MStateMachineObserver +*/ +void CProtocolManager::MeasurementControlTimeout() + { + // Store assistance data error + iAssistMgr->Error(KErrTimedOut); + + // Check if we have an active state machine to handle this, + // otherwise silently consume this indication. + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + if (NULL != activeMachine) + { + // Advise state machine of error + activeMachine->MeasurementControlTimeout(); + } + } + + +/** Handle network error reported +@see MStateMachineObserver +*/ +void CProtocolManager::NetworkErrorReported() + { + NetworkErrorInd(KErrDisconnected); + } + + +/** Perform assistance data request action. +This is called by state machines when they are in suitable state to +handle assistance data actions. + +The actions will arises from preceding assistance data requests and responses +which have been processed by the assistance data manager. +@see CAssistDataMgr::ProcessDataRequest() +@see CAssistDataMgr::StoreData() +@see CAssistDataMgr::Error() + +@see MStateMachineObserver +*/ +void CProtocolManager::DoAssistanceDataActions() + { + // Is there a data response error to be reported to LBS? + if (iAssistMgr->IsErrorToBeReported()) + { + // note: send any available valid data anyway + Gateway()->AssistanceDataInd(iAssistMgr->ErrorGroupMask(), iAssistMgr->ValidData(), iAssistMgr->ErrorReason()); + iAssistMgr->ErrorReported(); + } + + // Is there valid data to be reported to LBS? + if (iAssistMgr->IsDataToBeReported()) + { + Gateway()->AssistanceDataInd(iAssistMgr->ValidGroupMask(), iAssistMgr->ValidData(), KErrNone); + iAssistMgr->DataReported(); + } + + // Is there a request error to be reported to LBS? + if (iAssistMgr->IsRequestErrorToBeReported()) + { + Gateway()->AssistanceDataInd(iAssistMgr->RequestErrorMask(), iAssistMgr->ValidData(), KErrArgument); + iAssistMgr->RequestErrorReported(); + } + + // Is data required from the network? + if (iAssistMgr->IsDataToBeRequested()) + { + iAssistMgr->SendingRequest(); + Network()->MeasurementControlReq(iAssistMgr->RequestMask()); + // Start the timer for receiving additional assistance data + CStateMachineBase* activeMachine; + GetActiveStateMachine(activeMachine); + if (NULL != activeMachine) + { + activeMachine->StartAssistDataTimer(); + } + iAssistMgr->RequestSent(); + } + } + + + +/** Inform LBS of status update. +This is called when a new operation starts or when a current operation ends. + +@param aOperation Indicates the type of operation +@param aIsOperationStarting ETrue if operation is starting +*/ +void CProtocolManager::StatusUpdate( + CConfigManager::TConflictOp aOperation, + TBool aIsOperationStarting) + { + MLbsNetworkProtocolObserver::TLbsNetProtocolServiceMask mask = MLbsNetworkProtocolObserver::EServiceNone; + switch (aOperation) + { + case CConfigManager::EOpMoLr: + mask = MLbsNetworkProtocolObserver::EServiceSelfLocation; + break; + case CConfigManager::EOpNbLr: + mask = MLbsNetworkProtocolObserver::EServiceNetworkLocation; + break; + case CConfigManager::EOpMtLr: + mask = MLbsNetworkProtocolObserver::EServiceMobileTerminated; + break; + case CConfigManager::EOpNiLr: + mask = MLbsNetworkProtocolObserver::EServiceNetworkInduced; + break; + case CConfigManager::EOpX3p: + mask = MLbsNetworkProtocolObserver::EServiceTransmitThirdParty; + break; + + case CConfigManager::EOpNone: + default: + break; + }; + + if (aIsOperationStarting) + { + iActiveServiceMask |= mask; + } + else + { + iActiveServiceMask &= ~mask; + } +#pragma message ("Status updates ommitted for now") + // Gateway()->StatusUpdate(iActiveServiceMask); + }