--- /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 <ecom/implementationproxy.h>
+
+//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<TSuplMessageType>(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<TUint32>((Abs(iPosition.Latitude()) * 8388608.0 + 0.5) / 90.0);
+ posContent->iPositionEstimateContent->iLongitude = static_cast<TInt32>((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;
+}