diff -r a2efdd544abf -r b47902b73a93 networkprotocolmodules/suplprotocolmodule/SuplProtocol/src/suplmolrfsmsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkprotocolmodules/suplprotocolmodule/SuplProtocol/src/suplmolrfsmsession.cpp Fri Jun 04 10:34:15 2010 +0100 @@ -0,0 +1,689 @@ +// Copyright (c) 2008-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 for +// the MO-LR protocol state machine. +// +// + +/** + @file + @internalTechnology + @deprecated +*/ + +#include "suplmolrfsmsession.h" +#include "suplmolrstatehandler.h" +#include "suplrrlpstatemachine.h" +#include "suplgatewayinterface.h" +#include "suplend.h" +#include "supldevloggermacros.h" + +/** KSuplResponseTimerEvent +Identity of timer for when SUPL RESPONSE is expected from the network +*/ +const TInt KSuplResponseTimerEvent = 0x100; + +/** KSuplResponseTimerDurationInSec +Timer duration for when SUPL RESPONSE is expected from the network +*/ +const TInt KSuplResponseTimerDurationInSec = 10; + + +/** KMaxQueueEntry +Maximum number of messages waiting to be processed +in the state machine event store. +*/ +const TInt KMaxQueueEntry = 5; + + +/** Static constructor. +@param aObserver Reference to state machine observer. +@return A new instance of the CSuplMolrFsmSession class +*/ +CSuplMolrFsmSession* CSuplMolrFsmSession::NewL(MSuplFsmSessionObserver& aObserver, TSuplMolrMachineType aMachineType) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::NewL() Begin\n"); + CSuplMolrFsmSession* self = new (ELeave) CSuplMolrFsmSession(aObserver, aMachineType); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::NewL() End\n"); + return self; + } + +/** Standard constructor. +@param aObserver Reference to state machine observer. +*/ +CSuplMolrFsmSession::CSuplMolrFsmSession(MSuplFsmSessionObserver& aObserver, TSuplMolrMachineType aMachineType) +:CSuplFsmSessionBase(aObserver) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::CSuplMolrFsmSession() Begin\n"); + iLocReqType = MLbsNetworkProtocolObserver::EServiceSelfLocation; + iMachineType = aMachineType; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::CSuplMolrFsmSession() End\n"); + } + + +/** Standard destructor. +*/ +CSuplMolrFsmSession::~CSuplMolrFsmSession() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::~CSuplMolrFsmSession() Begin\n"); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::~CSuplMolrFsmSession() End\n"); + } + +/** Private second-stage constructor. +*/ +void CSuplMolrFsmSession::ConstructL() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::ConstructL() Begin\n"); + CActiveScheduler::Add(this); + + iEventStore = CSuplFsmEventStore::NewL(KMaxQueueEntry); + + // Create state handler + iStateHandler = CSuplMoLrStateHandler::NewL(*this); + + // Open up assistance data builder + iAssistanceDataBuilderSet.OpenL(); + + // Create a Positioning Protocol State Machine + iPositioningProtocol = CSuplRrlpFsm::NewL(*this,iAssistanceDataBuilderSet); + + // Create timers used during MO-LR protocol procedure + iSuplProtTimer = CLbsCallbackTimer::NewL(*this); + iSlpSettingsStore = CLbsHostSettingsStore::NewL(KLbsHostSettingsSuplStoreId); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::ConstructL() End\n"); + } + + +/** Retrieve machine type +@return TSuplMolrMachineType type of MOLR state machine +*/ +CSuplMolrFsmSession::TSuplMolrMachineType CSuplMolrFsmSession::MachineType() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::MachineType() Begin\n"); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::MachineType() End\n"); + return iMachineType; + } + + +/** GetHostId() +This method returns the ID of an entry in the HostSettings store +containing the address of the host (SLP) to connect to. +For MOLR, if a host in the store has been declared as "default", such +host will be used for the MOLR session. Otherwise, the last modified +network-provisioned host will be used. +If a host is not found in the store using the logic above, then a +host is created using the IMSI stored in the SIM (see "Auto +configuration of the H-SLP Address" in OMA-AD-SUPL-V1_0-20070615-A, +section 7.2.2). +@param aHostId the ID of the host selected for the MOLR +@return KErrNone if a valid host ID has been found +*/ +TInt CSuplMolrFsmSession::GetHostId(TLbsHostSettingsId& aHostId) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::GetHostId() Begin\n"); + TInt err = KErrNotFound; + TBool hostFound = EFalse; + if (iSlpSettingsStore) + { + TLbsHostSettingsSupl slpSettings; + TLbsHostSettingsId settingsId; + // Get the default SLP if one exists + err = iSlpSettingsStore->GetDefaultHostSettings(slpSettings, settingsId); + if (KErrNone == err) + { + aHostId = settingsId; + hostFound = ETrue; + } + else + { + // If no default SLP is present, get the + // network-provisioned SLP that has been + // modified most recently + TTime mostRecent = 0; + err = iSlpSettingsStore->RewindHostSettings(); + if (KErrNone == err) + { + while (KErrNone == err) + { + err = iSlpSettingsStore->GetNextHostSettingsByCreator(KLbsHostSettingsDevProvCreatorId, slpSettings, settingsId); + if (KErrNone == err) + { + if (mostRecent < slpSettings.LastModified()) + { + mostRecent = slpSettings.LastModified(); + aHostId = settingsId; + hostFound = ETrue; + } + } + } + } + } + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::GetHostId() End\n"); + if(!hostFound) + { + return GenerateHostId(aHostId); + } + + return KErrNone; + } + +/** Start SUPL RESPONSE timer +The state handler calls this when it has issued a SUPL START +to the network and it requires a response before the timer expires. +*/ +void CSuplMolrFsmSession::StartSuplResponseTimer() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::StartSuplResponseTimer() Begin\n"); + iSuplProtTimer->EventAfter(TTimeIntervalSeconds(KSuplResponseTimerDurationInSec), KSuplResponseTimerEvent); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::StartSuplResponseTimer() End\n"); + } + +/** Initialise internal state attributes. +This is used when new MO-LR procedure commences. +*/ +void CSuplMolrFsmSession::InitialiseProcedure() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::InitialiseProcedure() Begin\n"); + // Initialise state machine + InitialiseMachineBase(); + iCurrentState = EStateProcedureNull; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::InitialiseProcedure() End\n"); + } + + +/** State transition. +This method determines the next state to be adopted by the state machine. +@return TBool ETrue if the state has changed. +@param aForceRedo, indicates that the states entry action must be re-performed when there has been no change in state +*/ +TBool CSuplMolrFsmSession::SelectNextState(TBool& aForceRedo) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Begin\n"); + TBool stateChanged = ETrue; + aForceRedo = EFalse; + + // Regardless of current state, check first if an event has occurred + // that implies cancelling the machine (terminate session) + if (IsCancelPending()) + { + SetMachineAsCancelling(); + iCurrentState = (IsSessionConnected() && iSessionInProgress)? EStateSuplSessionEnded : EStatePosSessionEnded; + } + else + { + // Set new state + switch (iCurrentState) + { + + case EStateProcedureNull: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateProcedureNull\n"); + iCurrentState = EStateNetConnectionStarted; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateNetConnectionStarted\n"); + break; + + case EStateNetConnectionStarted: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateNetConnectionStarted\n"); + iCurrentState = EStateStartSent; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateStartSent\n"); + break; + + case EStateStartSent: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateStartSent\n"); + stateChanged = DetermineStateFromStartSent(); + break; + + case EStateResponseReceived: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateResponseReceived\n"); + iCurrentState = EStatePosInitSent; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosInitSent\n"); + break; + + case EStatePosInitSent: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePosInitSent\n"); + stateChanged = DetermineStateFromPosInitSent(); + break; + + case EStatePositioningInProgress: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePositioningInProgress\n"); + stateChanged = DetermineStateFromPositioningInProgress(aForceRedo); + break; + + case EStatePositionReceived: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePositionReceived\n"); + iCurrentState = EStatePosSessionEnded; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosSessionEnded\n"); + SetMachineAsNotCancellable(); + break; + + case EStateSuplSessionEnded: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateSuplSessionEnded\n"); + iCurrentState = EStatePosSessionEnded; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStatePosSessionEnded\n"); + break; + + case EStatePosSessionEnded: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStatePosSessionEnded\n"); + iCurrentState = EStateLbsSessionEnded; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateLbsSessionEnded\n"); + break; + + case EStateLbsSessionEnded: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateLbsSessionEnded\n"); + iCurrentState = EStateNetConnectionClosed; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateNetConnectionClosed\n"); + break; + + case EStateNetConnectionClosed: + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() entry state EStateNetConnectionClosed\n"); + // Procedure has completed + iCurrentState = EStateProcedureNull; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() Nex state: EStateProcedureNull\n"); + break; + + default: + SUPLLOG(ELogP3, "CSuplMolrFsmSession::SelectNextState() unknown entry state\n"); + ASSERT(EFalse); + break; + }; + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::SelectNextState() End\n"); + return stateChanged; + } + + +/** Complete the procedure. +*/ +void CSuplMolrFsmSession::CompleteProcedure() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::CompleteProcedure() Begin\n"); + // Complete state machine + CompleteMachineBase(); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::CompleteProcedure() End\n"); + } + +/** Complete a state transition. +This is called by the base class when a state transition has +concluded and it provides an opportunity for the state machine +to perform actions required immediately after this transition. + +The method can also initiate a further change of state. This is +relevant when the state machine is required to perform an autonomous +transition from one state to another e.g. this occurs when several +interactions are required arising from a single external trigger. +*/ +void CSuplMolrFsmSession::PostTransition() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::PostTransition() Begin\n"); + // Some states are transitory i.e. they require + // an automatic transition to the next state + if (IsCancelPending() || + ((EStateResponseReceived == iCurrentState) && (ESuplMolrCellBased == MachineType())) || + EStatePositionReceived == iCurrentState || + EStateSuplSessionEnded == iCurrentState || + EStatePosSessionEnded == iCurrentState || + EStateLbsSessionEnded == iCurrentState || + EStateNetConnectionClosed == iCurrentState) + { + // Perform a state transition + PerformTransition(); + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::PostTransition() End\n"); + } + + +/** Cancel the active procedure +*/ +void CSuplMolrFsmSession::CancelProcedure() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::CancelProcedure() Begin\n"); + // Kill all timers + iSuplProtTimer->Cancel(); + + SUPLLOG(ELogP1, "CSuplMolrFsmSession::CancelProcedure() End\n"); + } + + +/** Timer expired callback. +This is called by a CStateTimer object when the timer +has expired - the event is identified by aEvent parameter. +@param aTimerId The timer event identifier. +*/ +void CSuplMolrFsmSession::OnTimerEventL(TInt aTimerId) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::OnTimerEventL() Begin\n"); + // Perform relevant action for the expired timer + switch (aTimerId) + { + // Connection result timer + case KSessionConnectedTimerEvent: + CancelMachine(CSuplFsmSessionBase::ECancelNetwork,CSuplFsmSessionBase::EReasonTimerExpiry); + break; + + // SUPL RESPONSE timer + case KSuplResponseTimerEvent: + CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonTimerExpiry); + break; + + // SUPL POS timer + case KSuplPosTimerEvent: + CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonTimerExpiry); + break; + + case KSuplEndTimerEvent: + CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonTimerExpiry); + break; + + // Ignore unknown timer events + default: + break; + }; + + SUPLLOG(ELogP1, "CSuplMolrFsmSession::OnTimerEventL() End\n"); + } + + +//--------------------------------------------------------------------------------------------------------------------- +// -------------------------------- EVENT HANDLING METHODS ------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- + + +//----------------------------- EVENTS FROM PROTOCOL MANAGER (LBS) -------------------------- + +/** Handle LBS request for MO-LR +@param aSessionId The session ID supplied by LBS. +*/ +void CSuplMolrFsmSession::MoLrReq(const TLbsNetSessionId& aSessionId, const TLbsNetPosRequestOptionsBase& aOptions) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::MoLrReq() Begin\n"); + + // Initialise the new procedure + InitialiseProcedure(); + + // Store the supplied ID information + SetSessionId(aSessionId); + + // Store MOLR Options needed for SUPL START + // + if (KErrNone != StoreLocationRequest(aOptions)) + CancelMachine(CSuplFsmSessionBase::ECancelClosing, CSuplFsmSessionBase::EReasonNone); + + // Perform a state transition + PerformTransition(); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::MoLrReq() End\n"); + } + + +/** Handle LBS Location response +@param aReason Location response error reason. +@param aPosInfo The location information response from LBS. +*/ +void CSuplMolrFsmSession::LocationResp(TInt aReason, const TPositionInfoBase& aPosInfo) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::LocationResp() Begin\n"); + switch (aReason) + { + case KErrNone: + if(EStatePositioningInProgress == iCurrentState) + { + // While a SUPL POS session is in progress, the recipient of the location update is + // the Positioning Protocol state machine. + iPositioningProtocol->LocationResp(aReason, aPosInfo); + } + else + { + // SUPL state machine has no use for a location update. Ignore it. + } + break; + + case KPositionCalculationFutile: + // LBS unable to calculate a position using selected positioning method + CancelMachine(CSuplFsmSessionBase::ECancelClient, CSuplFsmSessionBase::EReasonFutilePosCalc); + break; + + default: + if(EStatePositioningInProgress == iCurrentState) + { + // Send the position and the error code to the positioning state machine for + // it to handle according to the specifications of the Positioning Protocol. + iPositioningProtocol->LocationResp(aReason, aPosInfo); + } + else + { + CancelMachine(ECancelSuplProt,EReasonNone); + } + break; + } + + SUPLLOG(ELogP1, "CSuplMolrFsmSession::LocationResp() End\n"); + } + +/** Handle LBS Assistance Data Request + +The Protocol Manager calls this method following an assitance data request from +LBS. However, the PM only does that if a location request had been sent +to LBS (which signals the point when the state machines can handle a request +for assitance data). Consequently assistance data requests are only handled +from states that may have resulted in a Location Request sent to LBS from the +state machine. + +@param aFilter Assistance data types being requested +*/ +void CSuplMolrFsmSession::AssistanceDataReq(const TLbsAssistanceDataGroup& aFilter) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::AssistanceDataReq() Begin\n"); + if (iCurrentState == EStatePositioningInProgress) + { + // While a SUPL POS session is in progress, the recipient of the assistance data + // request is the Positioning Protocol state machine, but only if the assistance + // data request is not empty. + if (aFilter != 0) + { + iPositioningProtocol->AssistanceDataRequest(aFilter); + } + else + { + // ignore assistance data request + // + } + } + else if (iCurrentState == EStateResponseReceived) + { + // The assistance data request can be sent to the SLP in a SUPL POS INIT + StoreAssistanceDataRequest(aFilter); + PerformTransition(); + } + else + { + // Assistance data request has arrived unsolicitedly from LBS and SUPL has no + // use for it. Log it and ignore it. + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::AssistanceDataReq() End\n"); + } + + +/** Handle a request to switch LBS session Id + +The Protocol Manager calls this method following a conflict whose resolution +requires that the MOLR procedure remains active but the session ID changes +when a message is sent to LBS (the session ID in SUPL messages must remain the +same) + + +@param aFilter Assistance data types being requested +*/ +void CSuplMolrFsmSession::AdoptNewLbsSessionId(const TLbsNetSessionId& aSessionId) +{ + SUPLLOG(ELogP1, "CSuplMolrFsmSession::AdoptNewLbsSessionId() Begin\n"); + iSessionIdReplaced = ETrue; + iReplacementSessionId = aSessionId; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::AdoptNewLbsSessionId() End\n"); +} + + +//----------------------------- EVENTS FROM POSITIONING PROTOCOL (RRLP) --------------------------- + +/** Handle a notification of availability of new assistance data from + the Positioning Protocol (RRLP) state machine. +*/ +void CSuplMolrFsmSession::ProcessAssistanceData(const TLbsAsistanceDataGroup& aGroupMask, TInt aReason) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessAssistanceData() Begin\n"); + ASSERT(iCurrentState == EStatePositioningInProgress); + iObserver.ProcessAssistanceData(aGroupMask, iAssistanceDataBuilderSet, aReason,LocReqType()); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessAssistanceData() End\n"); + } + +/** Handle a Location Request from the Positioning Protocol. +@param aQuality quality parameters for the location request. +@param aPosMethod positioning method requested by the Positioning Protocol +*/ +void CSuplMolrFsmSession::ProcessPositioningRequest(const TLbsNetPosRequestQuality& aQuality, const TLbsNetPosRequestMethod& aPosMethod) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessPositioningRequest() Begin\n"); + // Disregard this event if MOLR FSM is no longer in positioning state + // (this could happen if the SUPL session has changed state due to + // a cancel or error but the Positioning Protocol + // state machine has not been notified yet) + if (iCurrentState == EStatePositioningInProgress) + { + // Verify that the positioning method requested by the positioning + // state machine is supported by LBS + TLbsNetPosMethod selectedMethod;//only one to send to LBS + TLbsNetPosCapabilities capabilities; + iObserver.Gateway().GetCapabilities(capabilities); + if (PosMethodSupported(aPosMethod,selectedMethod,capabilities)) + { + TLbsNetPosRequestMethod posMethod; + posMethod.SetPosMethods(&selectedMethod, 1); + // SUPL MoLr state machine just passes the request on to Protocol Manager. + iObserver.LocationReq(LbsSessionId(), LocReqType(), aQuality, posMethod); + } + else + { + // The associated positioning protocol has sent a location request + // with an unsupported positioning method. Terminate. + CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonMethodMismatch); + } + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::ProcessPositioningRequest() End\n"); + } + +/** Handle a request from the Positioning Protocol state machine to send +a positioning protocol message to the network as the payload in a SUPL POS +@param aPositioningPayload Positioning Protocol (RRLP) message that will be payload of a SUPL POS message +*/ +void CSuplMolrFsmSession::PositioningPayloadToNetwork(const CSuplPosPayload* aPositioningPayload) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningPayloadToNetwork() Begin\n"); + + // Disregard this event if MOLR FSM is no longer in positioning state + // (this could happen if the SUPL session has changed state due to + // a cancel or error but this information the Positioning Protocol + // state machine has not been cancelled yet) + if (iCurrentState == EStatePositioningInProgress) + { + // As this event involves sending a SUPL POS to the network, + // run it through the MOLR state machine + // + StorePosPayload(aPositioningPayload); + // Perform a state transition + PerformTransition(); + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningPayloadToNetwork() End\n"); + } + +/** Handle error notification from Positioning Protocol +This is an unrecoverable error. Cancel state machine. +@param aError Error code reported by Postioning Protocol State Machine. +*/ +void CSuplMolrFsmSession::PositioningProtocolError(const TInt& aError) + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningProtocolError() Begin\n"); + (void)aError; + ASSERT(iCurrentState == EStatePositioningInProgress); + CancelMachine(CSuplFsmSessionBase::ECancelPosProt, CSuplFsmSessionBase::EReasonNone); + SUPLLOG(ELogP1, "CSuplMolrFsmSession::PositioningProtocolError() End\n"); + } + + +//--------------------------------------------------------------------------------------------------------------------- +// -------------------------------- STATE CHANGE METHODS --------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- + +/** Decide next state from EStateStartSent +@return TBool ETrue if the state has changed +*/ +TBool CSuplMolrFsmSession::DetermineStateFromStartSent() + { + SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent() Begin\n"); + TBool stateChanged = ETrue; + + // Check what SUPL Message was received. + // + const CSuplMessageBase* msg = NULL; + TBool messageAvailable = iEventStore->IsSuplMessageStored(msg); + + if (messageAvailable) + { + // Received message was stored as constant (read-only) but + // access to non-constant methods is needed + CSuplMessageBase* message = const_cast (msg); + if (CSuplMessageBase::ESuplEnd == message->MessageType()) + { + iSessionInProgress = EFalse; + CSuplEnd* suplEnd = static_cast (message); + + if (suplEnd->PositionPresent()) + { + iCurrentState = EStatePositionReceived; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent(). Next state : EStatePositionReceived\n"); + // The position is about to be sent to LBS. + // The states following will terminate the session. + // Handling a cancel would result in sending an + // unnecessary SUPL END to the SLP. + SetMachineAsNotCancellable(); + } + else + { + // Unexpected session termination. + // Remember this fact before switching state. + iEventStore->SetUnexpectedSuplEnd(); + iCurrentState = EStateLbsSessionEnded; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent(). Next state : EStateLbsSessionEnded\n"); + SetMachineAsNotCancellable(); + } + } + else if (CSuplMessageBase::ESuplResponse == message->MessageType()) + { + iCurrentState = EStateResponseReceived; + SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent(). Next state : EStateResponseReceived\n"); + } + else + { + // Unexpected SUPL Message was received + // + CancelMachine(CSuplFsmSessionBase::ECancelSuplProt,CSuplFsmSessionBase::EReasonUnexpectedMessage); + } + } + else + { + stateChanged = EFalse; + } + SUPLLOG(ELogP1, "CSuplMolrFsmSession::DetermineStateFromStartSent() End\n"); + return stateChanged; + }