diff -r 000000000000 -r 9cfd9a3ee49c networkprotocolmodules/networkprotocolmodule/LbsSuplTestProtocol/src/lbssupltestmodule.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkprotocolmodules/networkprotocolmodule/LbsSuplTestProtocol/src/lbssupltestmodule.cpp Tue Feb 02 01:50:39 2010 +0200 @@ -0,0 +1,989 @@ +// 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 class implementation of the ECOM plug-in +// interface for the LBS test Network Protocol Module. +// +// + +#include "lbssupltestmodule.h" +#include "lbssuplsocketlistener.h" +#include + +//const TUint32 KInetAddr1 = INET_ADDR(209,172,70,68);//SiRF server +const TUint32 KInetAddr2 = INET_ADDR(66,230,192,56);//SiRF sever +const TUint32 KLoopBackAddr = INET_ADDR(127,0,0,1);//Used by SiRF in session ID of SUPL RESPONSE -proxy mode- +const TUint KSuplPort = 7276; // standard SUPL TCP port. +const TInt KNetworkTimeout = 45000000; +const TInt KProtocolTimeout = 50000000; +const TInt KMaxTxBufferSize = 2048; // 2k Max size of SUPL messages sent +const TInt KMaxRxBufferSize = 8192; // 8k Max size of SUPL messages received + +// --------------------- SUPL TEST MODULE (ECom plug-in) -------------------------- + +/** The unique ID of this plug-in interface. +This corresponds to the interface UID specified in the .rss file +for this SUPL test module. +*/ +const TInt KPluginUidValue = 0x1028225B; + +CSuplProtocolModule* CSuplProtocolModule::NewL(TAny* aInitParams) + { + CSuplProtocolModule* self=new(ELeave) CSuplProtocolModule(aInitParams); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +CSuplProtocolModule::~CSuplProtocolModule() + { + iSocketServerSession.Close(); + } + + +CSuplProtocolModule::CSuplProtocolModule(TAny* aInitParams): + iObserver(REINTERPRET_CAST( + TAssistanceDataSourceModuleConstructionParams*, + aInitParams)->iAssistanceDataSourceObserver), + iNextSessionNumber(0) + { + } + +void CSuplProtocolModule::ConstructL() + { + // Open channel to Socket Server + User::LeaveIfError(iSocketServerSession.Connect()); + } + +CAssistanceDataSourceBase* CSuplProtocolModule::NewDataSourceL() + { + // Create a new number for the session + if (iNextSessionNumber == 1000) + { + iNextSessionNumber = 0; + } + + iNextSessionNumber++; + + return CSuplProtocolSession::NewL(iObserver, iSocketServerSession, iNextSessionNumber); + } + + +/** Defines the plug-in interface implementation UIDs, required by ECOM. +*/ +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KPluginUidValue, CSuplProtocolModule::NewL) + }; + + +/** Exported function for ECOM to retrieve implementations table +*/ +EXPORT_C +const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + + return ImplementationTable; + } + + +//--------------------- SUPL Session --------------------------------------------------------- + +CSuplProtocolSession::CSuplProtocolSession(MLbsAssistanceDataSourceObserver& aObserver, const TInt16& aSessionNumber): + CActive(EPriorityStandard), + iObserver(&aObserver), + iBuilderSet(NULL), + iSessionNumber(aSessionNumber) + { + // Attach to active scheduler + // + CActiveScheduler::Add(this); + + iAddress.SetPort(KSuplPort); + iAddress.SetAddress(KInetAddr2); + } + +void CSuplProtocolSession::ConstructL(RSocketServ& aSocketServer) + { + iTxBuf.CreateMaxL(KMaxTxBufferSize); + iRxBuf.CreateMaxL(KMaxRxBufferSize); + // Open a TCP socket + User::LeaveIfError(iSocket.Open(aSocketServer, KAfInet, KSockStream, KProtocolInetTcp)); + + + // Set SUPL port in socket + // + iSocket.SetLocalPort(KSuplPort); + + // Create a socket listener for SUPL messages + iSuplSocketListener = CSuplSocketListener::NewL(iSocket, iRxBuf); + + // Create the timer + iTimer = CPeriodic::NewL(CActive::EPriorityStandard); + } + +CSuplProtocolSession::~CSuplProtocolSession() + { + Cancel(); + iTxBuf.Close(); + iRxBuf.Close(); + delete iTimer; + delete iSuplSocketListener; + iSocket.Close(); + } + +/** +GetAssistanceData() Called by Network Simulator to request assitance data from the remote +server. + +@parameter aBuilderSet. The CSuplProtocolSession will set the fields of this builder with + the assistance data. +*/ +void CSuplProtocolSession::GetAssistanceData(RLbsAssistanceDataBuilderSet& aBuilderSet, const TLbsAssistanceDataGroup& aAssistanceDataFilter, const TCoordinate& aPosition) + { + + iBuilderSet = &aBuilderSet; + iAssistanceDataFilter = aAssistanceDataFilter; + iPosition = aPosition; + + // Validate parameters + if(aAssistanceDataFilter == 0) + { + iObserver->DataSourceNotification(KErrArgument); + } + else + { + // Set the correct state and force a transition of the state machine + if(iSessionState == EConnectedAwaitingRequest) + { + // Transition out of wait state + iSessionState = EAssistanceDataRequested; + } + else + { + // If in the process of collecting assistance data, cancel previous request and + // start over. + // Do not notify NetSim that previous assistance data retrieval won't be completed + // (it should know) + CancelGetAssistanceData(); + + // Flag that a request is pending + iAssistanceDataRequestPending = true; + } + + // Transition out of inactive states (EIdle and EConnectedAwaitingState) + if(!IsActive()) + { + PrepareSelfTransition(); + } + } + } + + +CSuplProtocolSession* CSuplProtocolSession::NewL(MLbsAssistanceDataSourceObserver& aObserver,RSocketServ& aSocketServer, const TInt16& aSessionNumber) + { + CSuplProtocolSession* self= new(ELeave) CSuplProtocolSession(aObserver,aSessionNumber); + CleanupStack::PushL(self); + self->ConstructL(aSocketServer); + CleanupStack::Pop(); + return self; + } + +void CSuplProtocolSession::RunL() + { + iTimer->Cancel(); + + // Deal with errors in socket operations + if (iStatus != KErrNone) + { + if ((iSessionState == EConnectingToRemoteServer) && (!iAssistanceDataRequestPending)) + { + // Disconnect without reporting to NetSim + iSessionState = EDisconnectingFromServer; + } + else if ((iAssistanceDataRequestPending) && (iStatus == KErrCancel)) + { + // Assume the cancellation has been due to a new request from NetSim + // Start over without reporting to NetSim. + iSessionState = EConnectingToRemoteServer; + } + else + { + // start disconnection and report to NetSim + iSessionState = ENetworkTimeout; + } + } + + switch(iSessionState) + { + + case EIdle: + ConnectToRemoteServer(); + break; + + case EConnectingToRemoteServer: + TransitionAccordingToRequestAvailability(); + break; + + case EConnectedAwaitingRequest: + // Nothing to be done in this state. + // This state is left when the Network + // Simulator requests assistance data + // (see GetAssistanceData()) + break; + + case EAssistanceDataRequested: + iAssistanceDataRequestPending = EFalse; + iSessionState = ESendingSuplStart; + SendSuplMessageL(ESuplStart); + break; + + case ESendingSuplStart: + // SuplStart sent. Wait for SuplResponse + iSessionState = EAwaitingSuplResponse; + ReadSuplMessage(); + break; + + case EAwaitingSuplResponse: + iSessionState = ESuplResponseAvailable; + DecodeSuplMessageL(ESuplResponse); //May set error state + break; + + case ESuplResponseAvailable: + iSessionState = ESendingSuplPosInit; + SendSuplMessageL(ESuplPosInit); + break; + + case ESendingSuplPosInit: + iSessionState = EAwaitingSuplPos; + ReadSuplMessage(); + break; + + case EAwaitingSuplPos: + iSessionState = ESuplPosAvailable; + DecodeSuplMessageL(ESuplPos); //May set error state + break; + + case ESuplPosAvailable: + iSessionState = ERrcPayloadDecodeComplete; + DecodeRRCPayloadL(); + PrepareSelfTransition(); + break; + + case ERrcPayloadDecodeComplete: + iSessionState = EEndingSession; + // Notify succesful exit to NetSim + iObserver->DataSourceNotification(KErrNone); + PrepareSelfTransition(); + break; + + case EProtocolError: + //Unexpected message. Notify unsuccesfull exit to NetSim + iObserver->DataSourceNotification(KErrCancel); + iAssistanceDataRequestPending = EFalse; + iSessionState = EDisconnectingFromServer; + PrepareSelfTransition(); + break; + + case ENetworkTimeout: + // Report to NetSim that something went wrong + iObserver->DataSourceNotification(iStatus.Int()); + iAssistanceDataRequestPending = EFalse; + iSessionState = EDisconnectingFromServer; + PrepareSelfTransition(); + break; + + case EDisconnectingFromServer: + iSessionState = EIdle; + iSocket.Shutdown(RSocket::ENormal,iStatus); + SetActive(); + break; + + case EEndingSession: + iSessionState = ESuplEndSent; + SendSuplMessageL(ESuplEnd); + break; + + case ESuplEndSent: + iSessionState = EConnectingToRemoteServer; + ReadSuplMessage(); + break; + + default: + Cancel(); + User::Leave(KErrGeneral); + break; + } + } + +/** +CancelGetAssistanceData. Cancels a previous request +for Assistance Data and starts actions to bring the state +machine to EConnectedAwaitingRequest again, where a new +request for assistance data can be serviced. + +If the session had been started with the remote server +to obtain Assistance Data, the session is first brought +down and the state machine will autonomously reconnect and +move on to EConnectedAwaitingRequest state. + +The Nework Simulator will not receive a notification of +cancellation of the previous request for assistance data. + +Note this cancelling method is unrelated to +CActive::Cancel()/DoCancel(). The state machine will remain +active and method RunL is expected to be called after this +method completes (unlike DoCancel()). + +@return Symbian error code. KErrNone if OK. +*/ +void CSuplProtocolSession::CancelGetAssistanceData() + { + + iTimer->Cancel(); + // Do not service pending requests + iAssistanceDataRequestPending = false; + switch (iSessionState) + { + case EIdle: + case EConnectingToRemoteServer: + case EConnectedAwaitingRequest: + case EDisconnectingFromServer: + case ENetworkTimeout: + case EProtocolError: + case EEndingSession: + // nothing to do (session not getting assistance data) + break; + + case EAssistanceDataRequested: + // Session not started with remote server yet. + // RunL will be called shortly as a self transition + // was prepared when this state was entered. + // Put the state machine in a position of + // transitioning towards EConnectedAwaitingRequest state. + iSessionState = EConnectingToRemoteServer; + break; + + case ESendingSuplStart: + case ESendingSuplPosInit: + // Cancel send operation. + // RunL will process KErrCancel case, + // setting the state to EDisconnectingFromServer. + iSocket.CancelWrite(); + break; + + case EAwaitingSuplResponse: + case EAwaitingSuplPos: + case ESuplEndSent: + // Cancel receive operation + // RunL will process KErrCancel case, + // setting the state to EDisconnectingFromServer. + iSuplSocketListener->Cancel(); + break; + + case ESuplResponseAvailable: + case ESuplPosAvailable: + case ERrcPayloadDecodeComplete: + // These three states have prepared + // self-transaction. When RunL gets + // executed, disconnect: + iSessionState = EDisconnectingFromServer; + break; + + default: + // Not a valid state + User::Invariant(); + break; + } + } + + +TInt CSuplProtocolSession::OnTimerEventL(TAny* aPtr) + { + CSuplProtocolSession* aSession = STATIC_CAST(CSuplProtocolSession*,aPtr); + if (aSession) + { + aSession->DoProcessTimeoutL(); + } + return KErrNone; + } + +void CSuplProtocolSession::DoProcessTimeoutL() +{ + iTimer->Cancel(); + + // Cancel async tasks to re-enter RunL with + // error code KErrCancel + switch(iSessionState) + { + case EConnectingToRemoteServer: + iSocket.CancelConnect(); + break; + case ESendingSuplStart: + case ESendingSuplPosInit: + iSocket.CancelWrite(); + break; + case EAwaitingSuplPos: + case EAwaitingSuplResponse: + iSuplSocketListener->Cancel(); + break; + default: + // No other state should have a timer running + Cancel(); + User::Leave(KErrGeneral); + break; + } +} + + +void CSuplProtocolSession::CreateSuplStartMessageL() + { + + CSuplMessageContent* suplMsgContent=CSuplMessageContent::NewLC(); + + // Build common part + suplMsgContent->iMessageChoice=ESuplStart; + BuildCommonPartL(suplMsgContent); + + suplMsgContent->iSuplStartContent=CSuplStartContent::NewL(); + + // Qop field is optional BUT required for the SiRF server to work with RRC + TBool qopPresent = ETrue; + suplMsgContent->iSuplStartContent->iQopPresent=qopPresent; + + // Set capabilities (mandatory) + suplMsgContent->iSuplStartContent->iSetCapabilitiesContent=CSuplSetCapabilitiesContent::NewL(); + BuildSetCapabilitiesL(suplMsgContent->iSuplStartContent->iSetCapabilitiesContent); + + //LocationId --- CellInfo + suplMsgContent->iSuplStartContent->iLocationIdContent=CSuplLocationIdContent::NewL(); + suplMsgContent->iSuplStartContent->iLocationIdContent->iCellInfoContent=CSuplCellInfoContent::NewL(); + BuildCellInfoL(suplMsgContent->iSuplStartContent->iLocationIdContent->iCellInfoContent, EGsmCellInformation); // Verify EGsmCellInformation + suplMsgContent->iSuplStartContent->iLocationIdContent->iLocationStatus= ECurrent; //TSuplLocationStatus + + // QoP + suplMsgContent->iSuplStartContent->iQoPContent=CSuplQoPContent::NewL(); + suplMsgContent->iSuplStartContent->iQoPContent->iVeraccPresent = EFalse; + suplMsgContent->iSuplStartContent->iQoPContent->iMaxLocAgePresent = EFalse; + suplMsgContent->iSuplStartContent->iQoPContent->iDelayPresent = EFalse; + suplMsgContent->iSuplStartContent->iQoPContent->iHoracc= 20; // Random value !!! + + + CSuplMessage* suplMessageEncoder=CSuplMessage::NewLC(*suplMsgContent); + + // Encode message + iTxBuf.SetLength(0); + suplMessageEncoder->EncodeL(iTxBuf); + + CleanupStack::PopAndDestroy(suplMessageEncoder); + CleanupStack::PopAndDestroy(suplMsgContent); + } + +void CSuplProtocolSession::CreateSuplEndMessageL() + { + + CSuplMessageContent* suplMsgContent=CSuplMessageContent::NewLC(); + + // Build common part + suplMsgContent->iMessageChoice=ESuplEnd; + BuildCommonPartL(suplMsgContent); + suplMsgContent->iSuplEndContent=CSuplEndContent::NewL(); + + // Position field should be false + suplMsgContent->iSuplEndContent->iPositionPresent=EFalse; + + // Status Code field should be false + suplMsgContent->iSuplEndContent->iStatusCodePresent=EFalse; + + // Ver field should be false + suplMsgContent->iSuplEndContent->iVerPresent=EFalse; + + CSuplMessage* suplMessageEncoder=CSuplMessage::NewLC(*suplMsgContent); + + // Encode message + iTxBuf.SetLength(0); + suplMessageEncoder->EncodeL(iTxBuf); + + CleanupStack::PopAndDestroy(suplMessageEncoder); + CleanupStack::PopAndDestroy(suplMsgContent); + } + +void CSuplProtocolSession::CreatePosInitMessageL() + { + CSuplMessageContent* suplMsgContent=CSuplMessageContent::NewLC(); + + // Build common part + suplMsgContent->iMessageChoice = ESuplPosInit; + BuildCommonPartL(suplMsgContent); + suplMsgContent->iSuplPosInitContent = CSuplPosInitContent::NewL(); + + // Request Assist Data field should be true + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataPresent=ETrue; + + // PosInit field should be false + suplMsgContent->iSuplPosInitContent->iSuplPosPresent=EFalse; + + // Position field should be true + suplMsgContent->iSuplPosInitContent->iPositionPresent=ETrue; + + // Ver field should be false + suplMsgContent->iSuplPosInitContent->iVerPresent=EFalse; + suplMsgContent->iSuplPosInitContent->iSetCapContent=CSuplSetCapabilitiesContent::NewL(); + + // Build Set Capabilities + BuildSetCapabilitiesL(suplMsgContent->iSuplPosInitContent->iSetCapContent); + + // Set Assistance Data types requested + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent=CSuplRequestedAssistDataContent::NewL(); + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iNavigationModelDataPresent=EFalse;// SiRF unsupported + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iDgpsCorrectionsRequested=EFalse; // NOT SUPPORTED + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iRealTimeIntegrityRequested=EFalse;// NOT SUPPORTED + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iUtcModelRequested=EFalse; // NOT SUPPORTED BY SIRF + + if(iAssistanceDataFilter & EAssistanceDataAlmanac) + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iAlmanacRequested=ETrue; + } + else + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iAlmanacRequested=EFalse; + } + + if(iAssistanceDataFilter & EAssistanceDataIonosphericModel) + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iIonosphericModelRequested=ETrue; + } + else + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iIonosphericModelRequested=EFalse; + } + + if(iAssistanceDataFilter & EAssistanceDataReferenceLocation) + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iReferenceLocationRequested=ETrue; + } + else + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iReferenceLocationRequested=ETrue; + } + + if(iAssistanceDataFilter & EAssistanceDataReferenceTime) + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iReferenceTimeRequested=ETrue; + } + else + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iReferenceTimeRequested=EFalse; + } + + if(iAssistanceDataFilter & EAssistanceDataAquisitionAssistance) + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iAcquisitionAssistanceRequested=ETrue; + } + else + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iAcquisitionAssistanceRequested=EFalse; + } + + if(iAssistanceDataFilter & EAssistanceDataNavigationModel) + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iNavigationModelRequested=ETrue; + } + else + { + suplMsgContent->iSuplPosInitContent->iRequestedAssistDataContent->iNavigationModelRequested=EFalse; + } + + // build cell info + suplMsgContent->iSuplPosInitContent->iLocationIdContent = CSuplLocationIdContent::NewL(); + suplMsgContent->iSuplPosInitContent->iLocationIdContent->iCellInfoContent=CSuplCellInfoContent::NewL(); + suplMsgContent->iSuplPosInitContent->iLocationIdContent->iLocationStatus = EStale; //TSuplLocationStatus + BuildCellInfoL(suplMsgContent->iSuplPosInitContent->iLocationIdContent->iCellInfoContent,EGsmCellInformation); + + // build Position info + suplMsgContent->iSuplPosInitContent->iPositionContent = CSuplPositionContent::NewL(); + BuildPositionInfoL(suplMsgContent->iSuplPosInitContent->iPositionContent); + + CSuplMessage* suplMessageEncoder=CSuplMessage::NewLC(*suplMsgContent); + + // Encode message + iTxBuf.SetLength(0); + suplMessageEncoder->EncodeL(iTxBuf); + + CleanupStack::PopAndDestroy(suplMessageEncoder); + CleanupStack::PopAndDestroy(suplMsgContent); + } + +TSuplMessageType CSuplProtocolSession::DoDecodeMessageL() + { + CSuplMessage* suplMessageDecoder=CSuplMessage::NewLC(); + + CSuplMessageContent* suplMessageResultContent=suplMessageDecoder->DecodeL(iRxBuf); + CleanupStack::PushL(suplMessageResultContent); + + // Keep in the session the bits of information needed from the messages sent from the remote + // server + // + switch (suplMessageResultContent->iMessageChoice) + { + case ESuplResponse: + // Keep the SLP part of the session ID + iSlpSessionId.Copy(suplMessageResultContent->iSuplSessionIdContent->iSlpSessionIdContent->iSessionId); + break; + case ESuplPos: + // Keep the offset into the rx buffer where the RRC payload is + iRrcOffset = suplMessageResultContent->iSuplPosContent->iPosPayloadContent->iPayloadStartBitPos; + break; + } + + TSuplMessageType messageType = static_cast(suplMessageResultContent->iMessageChoice); + + CleanupStack::PopAndDestroy(2, suplMessageDecoder); + + return messageType; + } + +void CSuplProtocolSession::DecodeRRCPayloadL() + { + CAssistanceDataDeliveryR3IEs* rrcPayLoad=CAssistanceDataDeliveryR3IEs::NewLC(iBuilderSet); + rrcPayLoad->DecodeL(iRxBuf, iRrcOffset); + CleanupStack::PopAndDestroy(rrcPayLoad); + } + +void CSuplProtocolSession::PrepareSelfTransition() + { + TRequestStatus* localStatus = &iStatus; + iStatus = KRequestPending; + SetActive(); + User::RequestComplete(localStatus, KErrNone); + } + +void CSuplProtocolSession::DoCancel() + { + iSocket.CancelWrite(); + iSuplSocketListener->Cancel(); + iTimer->Cancel(); + } + +void CSuplProtocolSession::BuildSetCapabilitiesL(CSuplSetCapabilitiesContent* aContent) + { + // SETCAPABILITY --- PosTechnology (Set based and autonomous only) + aContent->iPosTechnologyContent=CSuplPosTechnologyContent::NewL(); + aContent->iPosTechnologyContent->iAgpsSETassisted=EFalse; + aContent->iPosTechnologyContent->iAgpsSETBased=ETrue; + aContent->iPosTechnologyContent->iAutonomousGPS=ETrue; + aContent->iPosTechnologyContent->iAFLT=EFalse; + aContent->iPosTechnologyContent->iECID=EFalse; + aContent->iPosTechnologyContent->iEOTD=EFalse; + aContent->iPosTechnologyContent->iOTDOA=EFalse; + + // SETCAPABILITY --- PosMethod (prefer Set based) + aContent->iPrefMethod = EAGpsSETBasedPreferred; //TSuplPrefMethod + + // SETCAPABILITY --- PosProtocol (only RRC) + aContent->iPosProtocolContent=CSuplPosProtocolContent::NewL(); + aContent->iPosProtocolContent->iTia801=EFalse; + aContent->iPosProtocolContent->iRrlp=EFalse; + aContent->iPosProtocolContent->iRrc=ETrue; + } + +void CSuplProtocolSession::BuildCellInfoL(CSuplCellInfoContent* aContent, TCellInformationChoice aCellInfoChoice) + { + + aContent->iCellInformation = aCellInfoChoice; + + switch (aCellInfoChoice) + { + case EGsmCellInformation: + { + aContent->iGsmCellInformationContent=CSuplGsmCellInformationContent::NewL(); + TBool nmrPresent = EFalse; //Optional + aContent->iGsmCellInformationContent->iNMRPresent=nmrPresent; + + TBool taPresent = EFalse; //Optional + aContent->iGsmCellInformationContent->iTAPresent=taPresent; + + TInt refMCC = 234; // UK + aContent->iGsmCellInformationContent->iRefMCC=refMCC; + + TInt refMNC = 101; // 101 (O2), 151 (voda), 301(t-mobile), 331 (orange) + aContent->iGsmCellInformationContent->iRefMNC=refMNC; + + TInt refLAC = 12049; // Area code (it seems to be dependant on the network!) + aContent->iGsmCellInformationContent->iRefLAC=refLAC; + + TInt refCI = 1103; // Entirely dependant on the operator. + aContent->iGsmCellInformationContent->iRefCI=refCI; + } + break; + case EWcdmaCellInformation: + { + aContent->iWcdmaCellInformationContent=CSuplWcdmaCellInformationContent::NewL(); + TBool frequencyInfoPresent = EFalse; + aContent->iWcdmaCellInformationContent->iFrequencyInfoPresent=frequencyInfoPresent; + + TBool primaryScramblingCodePresent = EFalse; + aContent->iWcdmaCellInformationContent->iPrimaryScramblingCodePresent=primaryScramblingCodePresent; + + TBool measuredResultsListPresent = EFalse; + aContent->iWcdmaCellInformationContent->iMeasuredResultsListPresent=measuredResultsListPresent; + + TInt refMCC = 34; + aContent->iWcdmaCellInformationContent->iRefMCC=refMCC; + + TInt refMNC = 34; + aContent->iWcdmaCellInformationContent->iRefMNC=refMNC; + + TInt refUC = 1; + aContent->iWcdmaCellInformationContent->iRefUC=refUC; + } + break; + case ECdmaCellInformation: + { + // All parameters are mandatory + // + aContent->iCdmaCellInformationContent=CSuplCdmaCellInformationContent::NewL(); + TInt refNID = 1; + aContent->iCdmaCellInformationContent->iRefNID=refNID; + + TInt refSID = 1; + aContent->iCdmaCellInformationContent->iRefSID=refSID; + + TInt refBASEID = 1; + aContent->iCdmaCellInformationContent->iRefBASEID=refBASEID; + + TInt refBASELAT = 1; + aContent->iCdmaCellInformationContent->iRefBASELAT=refBASELAT; + + TInt reBASELONG = 1; + aContent->iCdmaCellInformationContent->iReBASELONG=reBASELONG; + + TInt refREFPN = 1; + aContent->iCdmaCellInformationContent->iRefREFPN=refREFPN; + + TInt refWeekNumber = 1; + aContent->iCdmaCellInformationContent->iRefWeekNumber=refWeekNumber; + + TInt refSeconds = 1; + aContent->iCdmaCellInformationContent->iRefSeconds=refSeconds; + } + break; + } + } + +void CSuplProtocolSession::BuildPositionInfoL(CSuplPositionContent* posContent) + { + posContent->iPositionEstimateContent = CSuplPositionEstimateContent::NewL(); + + if (iPosition.Latitude() >= 0) + { + posContent->iPositionEstimateContent->iLatitudeSign = ENorth; + } + else + { + posContent->iPositionEstimateContent->iLatitudeSign = ESouth; + } + + posContent->iVelocityPresent = EFalse; + posContent->iUtcTimeStamp.UniversalTime(); // Use the current time. SUPL server ignores actual value. + + posContent->iPositionEstimateContent->iUncertainty = EFalse; + posContent->iPositionEstimateContent->iConfidence = EFalse; + posContent->iPositionEstimateContent->iAltitudInfo = EFalse; + + // Set Location (in the future, get the NetSim to provide this) + posContent->iPositionEstimateContent->iLatitude = static_cast((Abs(iPosition.Latitude()) * 8388608.0 + 0.5) / 90.0); + posContent->iPositionEstimateContent->iLongitude = static_cast((iPosition.Longitude() * 2097152.0 + 0.5) / 45.0); + } + +void CSuplProtocolSession::BuildCommonPartL(CSuplMessageContent* aSuplMsgContent) + { + + //Message Version + TInt majorVersion =1; + TInt minVersion = 0; + TInt servindVersion =0; + aSuplMsgContent->iSuplVersionContent=CSuplVersionContent::NewL(); + aSuplMsgContent->iSuplVersionContent->iMaj=majorVersion; + aSuplMsgContent->iSuplVersionContent->iMin=minVersion; + aSuplMsgContent->iSuplVersionContent->iServind=servindVersion; + + //SET Session ID + TBool setsessionPresent = ETrue; + aSuplMsgContent->iSuplSessionIdContent=CSuplSessionIdContent::NewL(); + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdPresent=setsessionPresent; + + + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent=CSuplSetSessionIdContent::NewL(); + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSessionId=iSessionNumber; + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSetIdContent=CSuplSetIdContent::NewL(); + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSetIdContent->iSetIdType= ESuplIPAddress; //TSuplSetIdType + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSetIdContent->iIpAddressContent=CSuplIpAddressContent::NewL(); + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSetIdContent->iIpAddressContent->iIpAddressType=ESuplIpV4AddressChoice;//TSuplIpAddressType; + + + // Find out own address from socket + // + TInetAddr localAddress; + iSocket.LocalName(localAddress); + TUint32 address = localAddress.Address(); + //aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSetIdContent->iIpAddressContent->iIpAddress.Copy(address); + TBuf8<4> theLocalAddress(4); + TUint8 aByteOfTheAddress = 0; + aByteOfTheAddress = address; + theLocalAddress[3]= aByteOfTheAddress; + aByteOfTheAddress = address >>8; + theLocalAddress[2]= aByteOfTheAddress; + aByteOfTheAddress = address >> 16; + theLocalAddress[1]= aByteOfTheAddress; + aByteOfTheAddress = address >> 24; + theLocalAddress[0]= aByteOfTheAddress; + aSuplMsgContent->iSuplSessionIdContent->iSetSessionIdContent->iSetIdContent->iIpAddressContent->iIpAddress.Copy(theLocalAddress); + + //SLP Session ID -not sent in START- + if (aSuplMsgContent->iMessageChoice == ESuplStart) + { + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdPresent=EFalse; + } + else + { + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdPresent=ETrue; + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent=CSuplSlpSessionIdContent::NewL(); + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent->iSessionId.Copy(iSlpSessionId); + + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent->iSlpAddressContent=CSuplSlpAddressContent::NewL(); + + // Address provided by SiRF is IPv4 + // + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent->iSlpAddressContent->iSlpAddressType= ESuplSlpIpAddressChoice; + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent->iSlpAddressContent->iIpAddressContent=CSuplIpAddressContent::NewL(); + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent->iSlpAddressContent->iIpAddressContent->iIpAddressType = ESuplIpV4AddressChoice; + + // Use loopback address 127.0.0.1 (received in RESPONSE, proxy mode). + TUint32 serverAddress = KLoopBackAddr; + TBuf8<4> theRemoteAddress(4); + TUint8 aByteOfTheRemoteAddress = 0; + aByteOfTheRemoteAddress = serverAddress; + theRemoteAddress[3]= aByteOfTheRemoteAddress; + aByteOfTheRemoteAddress = serverAddress >>8; + theRemoteAddress[2]= aByteOfTheRemoteAddress; + aByteOfTheRemoteAddress = serverAddress >> 16; + theRemoteAddress[1]= aByteOfTheRemoteAddress; + aByteOfTheRemoteAddress = serverAddress >> 24; + theRemoteAddress[0]= aByteOfTheRemoteAddress; + aSuplMsgContent->iSuplSessionIdContent->iSlpSessionIdContent->iSlpAddressContent->iIpAddressContent->iIpAddress.Copy(theRemoteAddress); + } + } + + +void CSuplProtocolSession::ReadSuplMessage() + { + iTimer->Cancel(); + // Start "listen" timer + iTimer->Start(KProtocolTimeout, KProtocolTimeout, TCallBack(OnTimerEventL,this)); + iSuplSocketListener->ReadMessage(iStatus); + SetActive(); + } + + +void CSuplProtocolSession::SendSuplMessageL(TSuplMessageType aSuplMessageType) + { + iTimer->Cancel(); + + switch(aSuplMessageType) + { + case ESuplStart: + CreateSuplStartMessageL(); + break; + + case ESuplPosInit: + CreatePosInitMessageL(); + break; + + case ESuplEnd: + CreateSuplEndMessageL(); + break; + + default: + // unexpected message type + User::Leave(KErrGeneral); + break; + } + + // The encoding process does no set the final length of the encoded message + // in the first two bytes of the SUPL message. Do it now. + TUint16 encodedMessageLength = iTxBuf.Length(); + TUint8 oneByteOftheLength = encodedMessageLength; + iTxBuf[1] = oneByteOftheLength; //Less significant byte + oneByteOftheLength = (encodedMessageLength >> 8); + iTxBuf[0] = oneByteOftheLength; + + // Start send timer + iTimer->Start(KNetworkTimeout, KNetworkTimeout, TCallBack(OnTimerEventL,this)); + // Send message + iSocket.Write(iTxBuf, iStatus); + SetActive(); + } + +void CSuplProtocolSession::DecodeSuplMessageL(TSuplMessageType aExpectedSuplMessageType) + { + iTimer->Cancel(); + if (aExpectedSuplMessageType != DoDecodeMessageL()) + { + iSessionState = EProtocolError; + } + PrepareSelfTransition(); + } + +void CSuplProtocolSession::ConnectToRemoteServer() + { + iTimer->Cancel(); + iTimer->Start(KNetworkTimeout, KNetworkTimeout, TCallBack(OnTimerEventL,this)); + iSocket.Connect(iAddress,iStatus); + iSessionState = EConnectingToRemoteServer; + SetActive(); + } + +/** +TransitionAccordingToRequestStatus() +This method is called by the CSuplProtocolSession after +having connected to the remote server to decide if the +next state must be a waiting state (when there is no request +for assistance data from the NetSim to service). +*/ +void CSuplProtocolSession::TransitionAccordingToRequestAvailability() + { + iTimer->Cancel(); + if(iAssistanceDataRequestPending) + { + // Start servicing pending request + iAssistanceDataRequestPending = EFalse; + iSessionState = EAssistanceDataRequested; + PrepareSelfTransition(); + } + else + { + // Go into a waiting state. Do not self-transition. + // CSuplProtocolSession will remain inactive until + // GetAssistanceData() is called by NetSim. + iSessionState = EConnectedAwaitingRequest; + } + } + +TInt CSuplProtocolSession::RunError(TInt aError) +{ + iObserver->DataSourceNotification(aError); + return KErrNone; +}