locationrequestmgmt/locationserver/src/EPos_CPosSession.cpp
changeset 0 9cfd9a3ee49c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationrequestmgmt/locationserver/src/EPos_CPosSession.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,526 @@
+// Copyright (c) 2005-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:
+//
+
+
+
+// INCLUDE FILES
+#include <e32base.h>
+#include <lbs.h>
+#include "lbslocservermessageenums.h"
+#include <lbs/epos_mposmodulesobserver.h>
+#include <lbs/epos_cposmoduleidlist.h>
+#include <lbs/epos_cpositioner.h>
+#include "EPos_PositionerConstructParams.h"
+#include "lbsdevloggermacros.h"
+#include "eposuid.hrh"
+
+#ifdef _DEBUG
+#include <lbs/epos_cpostrace.h>
+#endif
+
+#include "EPos_CPosSession.h"
+#include "EPos_CPosSubSession.h"
+#include "EPos_CPosServer.h"
+#include "EPos_CPosSubsessionRegistry.h"
+#include "EPos_Global.h"
+#include "EPos_CPosModulesStatus.h"
+#include "epos_cposmodulessettings.h"
+
+
+// CONSTANTS
+#ifdef _DEBUG
+_LIT(KTraceFileName, "EPos_CPosSession.cpp");
+#endif
+
+const TPositionModuleId KPosDefaultModule = { KPosDefaultPsyImplUid };
+const TPositionModuleId KPosStrategyModule = { KPosStrategyPsyImplUid };
+
+const TInt KParamCriteria = 0;
+const TInt KParamNumModules = 0;
+const TInt KParamModuleIdOpen = 0;
+const TInt KParamModuleIdGetInfo = 0;
+const TInt KParamModuleIdGetStatus = 0;
+const TInt KParamModuleIdGetDefault = 0;
+const TInt KParamModuleInfo = 1;
+const TInt KParamModuleStatusGet = 1;
+const TInt KParamSubsession = 3;
+
+// ================= MEMBER FUNCTIONS =======================
+
+/**
+ * C++ constructor.
+ */
+CPosSession::CPosSession(CPosServer& aServer,
+                         CPosModuleSettings& aModuleSettings,
+                         CPosModulesStatus& aModulesStatus,
+                         CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub)
+    : iPosServer(aServer),
+      iModuleSettings(aModuleSettings),
+      iModulesStatus(aModulesStatus),
+      iLocMonitorReqHandlerHub(aLocMonitorReqHandlerHub)
+    {      
+    }
+
+/**
+ * C++ destructor.
+ */
+CPosSession::~CPosSession()
+    {
+
+    delete iSubSessionRegistry;
+    
+    // The flag iServerShutdown prevents calling the server or its members if
+    // it is already destroyed.
+    if (!iServerShutdown)
+        {
+        iModulesStatus.NotifySessionClosed(this); 
+        iLocMonitorReqHandlerHub.NotifySessionClosed( const_cast<const CSession2*>( static_cast<CSession2*> (this) ) ); //TODO ????????????????????????????????????????????
+        
+        if (iDecrementSessions)
+            {
+            iPosServer.DecrementSessions();
+            }
+        }
+    }
+
+/**
+ * Two-phased constructor.
+ *
+ * @param aServer Pointer to the server Active Object
+ * @param aModules Modules settings.
+ * @param aModulesStatus Pointer to the ModulesStatus object.
+ * @param aLastPositionHandler Last Position Handler.
+ * @return Pointer to a new instance of CPosSession
+ */
+CPosSession* CPosSession::NewL(CPosServer& aServer,
+                               CPosModuleSettings& aModuleSettings,
+                               CPosModulesStatus& aModulesStatus,
+                               CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub)
+    {
+    CPosSession* self = new (ELeave)
+        CPosSession(
+            aServer, 
+            aModuleSettings, 
+            aModulesStatus, 
+            aLocMonitorReqHandlerHub);
+            
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+/**
+ * Symbian destructor.
+ */
+void CPosSession::ConstructL()
+    {
+    iSubSessionRegistry = CPosSubsessionRegistry::NewL();
+
+    // This call will also cancel any server shutdown in progress.
+    iPosServer.IncrementSessions();
+    iDecrementSessions = ETrue;
+
+    }
+
+/**
+ * From CSession2
+ *
+ * This function services all requests from clients.
+ */
+void CPosSession::ServiceL(const RMessage2& aMessage)
+    {
+    LBSLOG2(ELogP1, "CPosSession::ServiceL function called with Function() = %u\n", aMessage.Function());
+
+    switch (aMessage.Function())
+        {
+        case ELbsPositionerOpenModuleId:
+		    OpenFromModuleIdL(aMessage);
+		    break;
+	    case ELbsPositionerOpen:
+		    OpenDefaultPositionerL(aMessage);
+		    break;
+	    case ELbsPositionerOpenCriteria:
+		    OpenPositionerFromCriteriaL(aMessage);
+		    break;
+	    case ELbsPositionerClose:
+		    ClosePositioner(aMessage);
+		    break;
+	    case ELbsGetDefaultModuleId:
+		    GetDefaultModuleIdL(aMessage);
+		    break;
+	    case ELbsGetNumModules:
+		    GetNumModulesL(aMessage);
+		    break;
+	    case ELbsGetModuleInfoByIndex:
+		    GetModuleInfoByIndexL(aMessage);
+		    break;
+	    case ELbsGetModuleInfoById:
+		    GetModuleInfoByIdL(aMessage);
+		    break;
+	    case ELbsGetModuleStatus:
+		    GetModuleStatusL(aMessage);
+		    break;
+	    case ELbsNotifyModuleStatusEvent:
+		    NotifyModuleStatusEventL(aMessage);
+		    break;
+	    case ELbsEmptyLastKnownPositionStore:
+	    	EmptyLastKnownPositionStoreL(aMessage);
+	    	break;
+	    case ELbsServerCancelAsyncRequest:
+			LBS_RDEBUG("Client", "LBS", "CancelAsyncRequest");
+            HandleCancelAsyncRequestL(aMessage);
+		    break;
+        default:
+            ForwardToSubSessionL(aMessage);
+		    break;
+        }
+    }
+
+/**
+ * From CSession2
+ *
+ * This function is called when ServiceL leaves.
+ */
+void CPosSession::ServiceError(const RMessage2& aMessage, TInt aError)
+    {
+    DEBUG_TRACE("Client's request failed with error", aError)
+    CSession2::ServiceError(aMessage, aError);
+    }
+
+/**
+ * Called when a change has been detected in the location settings. 
+ * @param aEvent Event information
+ */
+void CPosSession::HandleSettingsChangeL(TPosModulesEvent aEvent)
+    {
+    // For all subSessions, call HandleSettingsChangeL()
+    TInt nrOfSubSessions = iSubSessionRegistry->Count();
+    for (TInt i = 0; i < nrOfSubSessions; i++)
+        {
+        CPosSubSession* subSession = 
+            static_cast <CPosSubSession*> 
+            (iSubSessionRegistry->SubSessionFromIndex(i));
+		if (subSession)
+			{
+			subSession->HandleSettingsChangeL(aEvent);
+			}
+        }
+    }
+
+/**
+ * Called when the server class is shutting down.
+ */
+void CPosSession::NotifyServerShutdown()
+    {
+    DEBUG_TRACE("NotifyServerShutdown", __LINE__)
+
+    iServerShutdown = ETrue;
+    TInt nrOfSubSessions = iSubSessionRegistry->Count();
+    
+    iLocMonitorReqHandlerHub.NotifyServerShutDown(); //TODO ????????????????????????????????????????????
+    
+    for (TInt i = 0; i < nrOfSubSessions; i++)
+        {
+        CPosSubSession* subSession = 
+            static_cast <CPosSubSession*> 
+            (iSubSessionRegistry->SubSessionFromIndex(i));
+        if (subSession)
+			{
+			subSession->NotifyServerShutdown();
+			}
+        }
+    }
+
+void CPosSession::OpenFromModuleIdL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionerOpenModuleId", __LINE__)
+
+	TPckgBuf<TPositionModuleId> moduleIdBuf;
+    User::LeaveIfError(Global::Read(aMessage, KParamModuleIdOpen, moduleIdBuf));
+    CreateSubSessionL(moduleIdBuf(), EFalse, aMessage);
+    RequestComplete(aMessage, KErrNone);
+    }
+
+void CPosSession::OpenDefaultPositionerL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionerOpen(Default)", __LINE__)
+    CreateSubSessionL(KPosDefaultModule, ETrue, aMessage);
+	RequestComplete(aMessage, KErrNone);
+    }
+
+void CPosSession::OpenPositionerFromCriteriaL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionerOpenCriteria", __LINE__)
+
+    // Read Criteria
+	TPckgBuf<TPositionCriteria> criteria;
+    User::LeaveIfError(Global::Read(aMessage, KParamCriteria, criteria));
+    CreateSubSessionL(KPosStrategyModule, ETrue, aMessage);
+    RequestComplete(aMessage, KErrNone);
+    }
+
+void CPosSession::ClosePositioner(const RMessage2& aMessage)
+    {
+    
+    iLocMonitorReqHandlerHub.NotifySubSessionClosed(aMessage);
+    
+    TInt handle = aMessage.Int3();
+    iSubSessionRegistry->CloseSubSession(handle);
+
+	RequestComplete(aMessage, KErrNone);
+
+    DEBUG_TRACE("EPositionerClose", __LINE__)
+    }
+
+void CPosSession::GetDefaultModuleIdL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerGetDefaultModuleId", __LINE__)
+
+    CPosModuleIdList* moduleList = iModuleSettings.ModuleIdListL();
+    CleanupStack::PushL( moduleList );
+    TInt nrOfModules = moduleList->Count();
+    TInt res = KErrNotFound;
+
+    for (TInt i = 0; (i < nrOfModules) && (res == KErrNotFound); i++)
+        {
+        TPositionModuleInfo candidate;
+        iModuleSettings.GetModuleInfoL((*moduleList)[i], candidate);
+
+        if (candidate.IsAvailable())
+            {
+            TPckg<TPositionModuleId> moduleId(candidate.ModuleId());
+            User::LeaveIfError(Global::Write(aMessage, KParamModuleIdGetDefault, moduleId));
+            res = KErrNone;
+            }
+        }
+
+    CleanupStack::PopAndDestroy(moduleList);
+    RequestComplete(aMessage, res);
+    }   
+
+void CPosSession::GetNumModulesL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerGetNumModules", __LINE__)
+
+    CPosModuleIdList* moduleList = iModuleSettings.ModuleIdListL();
+    TInt num = moduleList->Count();
+    delete moduleList;
+
+    TPckg<TUint> numPackage(num);
+    User::LeaveIfError(Global::Write(aMessage, KParamNumModules, numPackage));
+    RequestComplete(aMessage, KErrNone);
+    }
+
+void CPosSession::GetModuleInfoByIndexL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerGetModuleInfoByIndex in", __LINE__)
+
+    // module index
+    TInt modIndex = aMessage.Int0();
+
+    CPosModuleIdList* moduleIdList = iModuleSettings.ModuleIdListL();
+    CleanupStack::PushL( moduleIdList );
+    if (modIndex >= moduleIdList->Count() || modIndex < 0)
+        {
+        User::Leave(KErrNotFound);
+        }
+    TPositionModuleId moduleId = (*moduleIdList)[modIndex];
+
+    // module info
+    HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleInfo);
+
+    TPositionModuleInfoBase* moduleInfoBase =
+        reinterpret_cast<TPositionModuleInfoBase*>(
+        const_cast<TUint8*>(buffer->Ptr()));
+
+    Global::ValidatePositionClassBufferL(*moduleInfoBase, buffer->Des());
+    // TPositionModuleInfo is the only class supported by CPosModules
+    Global::ValidatePositionClassTypeL(*moduleInfoBase, EPositionModuleInfoClass);
+    DEBUG_TRACE("Buffer validation done", __LINE__)
+
+    CleanupStack::PopAndDestroy(2, moduleIdList);
+
+    // TPositionModuleInfo contains descriptor. If it is corrupt 
+    // (malicious client) then writing to this will panic server
+    // Local instance of TPositionModuleInfo is created to be sure
+    // that module name descriptor is not corrupt
+
+    TPositionModuleInfo modInfo;
+    iModuleSettings.GetModuleInfoL(moduleId, modInfo);
+
+    TPckg<TPositionModuleInfo> modInfoPack(modInfo);
+    User::LeaveIfError(Global::Write(aMessage, KParamModuleInfo, modInfoPack));
+
+    RequestComplete(aMessage, KErrNone);
+    DEBUG_TRACE("EPositionServerGetModuleInfoByIndex out", __LINE__)
+    }
+
+void CPosSession::GetModuleInfoByIdL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerGetModuleInfoById in", __LINE__)
+
+    TPckgBuf<TPositionModuleId> moduleIdBuf;
+	User::LeaveIfError(Global::Read(aMessage, KParamModuleIdGetInfo, moduleIdBuf));
+    TPositionModuleId moduleId = moduleIdBuf();
+
+    HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleInfo);
+
+    TPositionModuleInfoBase* moduleInfoBase = 
+	    reinterpret_cast<TPositionModuleInfoBase*>(
+        const_cast<TUint8*>(buffer->Ptr()));
+
+    Global::ValidatePositionClassBufferL(*moduleInfoBase, buffer->Des());
+    // TPositionModuleInfo is the only class supported by CPosModules
+    Global::ValidatePositionClassTypeL(*moduleInfoBase, EPositionModuleInfoClass);
+    DEBUG_TRACE("Buffer validation done", __LINE__)
+
+    CleanupStack::PopAndDestroy(buffer);
+
+    // TPositionModuleInfo contains descriptor. If it is corrupt 
+    // (malicious client) then writing to this will panic server
+    // Local instance of TPositionModuleInfo is created to be sure
+    // that module name descriptor is not corrupt
+
+    TPositionModuleInfo modInfo;
+    iModuleSettings.GetModuleInfoL(moduleId, modInfo);
+
+    TPckg<TPositionModuleInfo> modInfoPack(modInfo);
+    User::LeaveIfError(Global::Write(aMessage, KParamModuleInfo, modInfoPack));
+
+    RequestComplete(aMessage, KErrNone);
+    DEBUG_TRACE("EPositionServerGetModuleInfoById out", __LINE__)
+    }
+
+void CPosSession::GetModuleStatusL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerGetModuleStatus in", __LINE__)
+
+    TPckgBuf<TPositionModuleId> moduleIdBuf;
+	User::LeaveIfError(Global::Read(aMessage, KParamModuleIdGetStatus, moduleIdBuf));
+    TPositionModuleId moduleId = moduleIdBuf();
+
+    HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleStatusGet);
+
+    // Read module status and write back to client
+    TPositionModuleStatusBase* moduleStatusBase = 
+	    reinterpret_cast<TPositionModuleStatusBase*>(
+        const_cast<TUint8*>(buffer->Ptr()));
+
+    Global::ValidatePositionClassBufferL(*moduleStatusBase, buffer->Des());
+
+    User::LeaveIfError ( 
+        iModulesStatus.GetModuleStatus(moduleId, *moduleStatusBase) );
+    User::LeaveIfError(Global::Write(aMessage, KParamModuleStatusGet, *buffer));
+
+    CleanupStack::PopAndDestroy(buffer);
+	RequestComplete(aMessage, KErrNone);
+    DEBUG_TRACE("EPositionServerGetModuleStatus out", __LINE__)
+    }
+
+void CPosSession::NotifyModuleStatusEventL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerNotifyModuleStatusEvent", __LINE__)
+
+    iModulesStatus.NotifyModuleStatusEventL(aMessage, this);
+    }
+
+void CPosSession::NotifyModuleStatusEventCancelL(const RMessage2& aMessage)
+    {
+    DEBUG_TRACE("EPositionServerNotifyModuleStatusEventCancel", __LINE__)
+
+    iModulesStatus.CancelNotifyModuleStatusEventL(this);
+    RequestComplete(aMessage, KErrNone);
+    }
+
+void CPosSession::HandleCancelAsyncRequestL(const RMessage2& aMessage)
+    {
+    switch (aMessage.Int0())
+        {
+        case KServerNotifyModuleStatusEventSymbian:
+        case KServerNotifyModuleStatusEventVariant:
+        case ELbsNotifyModuleStatusEvent:                 // TODO Verify
+	        NotifyModuleStatusEventCancelL(aMessage);
+            break;
+        case ELbsEmptyLastKnownPositionStore:
+        	EmptyLastKnownPositionStoreCancelL(aMessage); // TODO Verify
+        
+        default:
+            RequestComplete(aMessage, KErrNotSupported);
+            break;
+        }
+    }
+
+void CPosSession::EmptyLastKnownPositionStoreL(const RMessage2& aMessage)
+	{
+	
+	iLocMonitorReqHandlerHub.EmptyLastKnownPosStoreReqL(aMessage);
+	
+	}
+
+void CPosSession::EmptyLastKnownPositionStoreCancelL(const RMessage2& aMessage)
+	{
+	
+	iLocMonitorReqHandlerHub.CancelEmptyLastKnownPosStoreReqL(aMessage);
+	
+	}
+
+
+void CPosSession::CreateSubSessionL(TPositionModuleId aId, TBool aIsProxy, const RMessage2& aMessage)
+	{
+    CPosSubSession* subSession = CPosSubSession::NewLC(
+        iModuleSettings, 
+        iLocMonitorReqHandlerHub,
+        aId,
+        aIsProxy,
+        &iModulesStatus,
+        &iModulesStatus);
+
+    TInt subSessionHandle = iSubSessionRegistry->AddInstanceL(subSession);
+    CleanupStack::Pop(subSession); // Now owned by registry
+    
+    // Set the client subsession identifier.
+    TPckg<TInt> handlePackage(subSessionHandle);
+    TInt err = Global::Write(aMessage, KParamSubsession, handlePackage);
+    if (err)
+        {
+        iSubSessionRegistry->CloseSubSession(subSessionHandle);
+        User::Leave(err);
+        }
+    DEBUG_TRACE("Subsession created successfully", __LINE__)
+	}
+
+void CPosSession::ForwardToSubSessionL(const RMessage2& aMessage)
+    {
+    CPosSubSession* subSession =
+        iSubSessionRegistry->SubSessionFromHandleL(aMessage.Int3());
+
+    if (!subSession)
+		{
+        User::Leave(KErrNotSupported);
+        }
+
+    subSession->ServiceL(aMessage); 
+    }
+
+void CPosSession::RequestComplete(const RMessage2& aMessage, TInt aCompleteCode)
+    {
+    if (!aMessage.IsNull())
+        {
+        aMessage.Complete(aCompleteCode);
+        }
+    }
+
+//  End of File