locationrequestmgmt/locationserver/src/EPos_CPosSession.cpp
changeset 0 9cfd9a3ee49c
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <e32base.h>
       
    20 #include <lbs.h>
       
    21 #include "lbslocservermessageenums.h"
       
    22 #include <lbs/epos_mposmodulesobserver.h>
       
    23 #include <lbs/epos_cposmoduleidlist.h>
       
    24 #include <lbs/epos_cpositioner.h>
       
    25 #include "EPos_PositionerConstructParams.h"
       
    26 #include "lbsdevloggermacros.h"
       
    27 #include "eposuid.hrh"
       
    28 
       
    29 #ifdef _DEBUG
       
    30 #include <lbs/epos_cpostrace.h>
       
    31 #endif
       
    32 
       
    33 #include "EPos_CPosSession.h"
       
    34 #include "EPos_CPosSubSession.h"
       
    35 #include "EPos_CPosServer.h"
       
    36 #include "EPos_CPosSubsessionRegistry.h"
       
    37 #include "EPos_Global.h"
       
    38 #include "EPos_CPosModulesStatus.h"
       
    39 #include "epos_cposmodulessettings.h"
       
    40 
       
    41 
       
    42 // CONSTANTS
       
    43 #ifdef _DEBUG
       
    44 _LIT(KTraceFileName, "EPos_CPosSession.cpp");
       
    45 #endif
       
    46 
       
    47 const TPositionModuleId KPosDefaultModule = { KPosDefaultPsyImplUid };
       
    48 const TPositionModuleId KPosStrategyModule = { KPosStrategyPsyImplUid };
       
    49 
       
    50 const TInt KParamCriteria = 0;
       
    51 const TInt KParamNumModules = 0;
       
    52 const TInt KParamModuleIdOpen = 0;
       
    53 const TInt KParamModuleIdGetInfo = 0;
       
    54 const TInt KParamModuleIdGetStatus = 0;
       
    55 const TInt KParamModuleIdGetDefault = 0;
       
    56 const TInt KParamModuleInfo = 1;
       
    57 const TInt KParamModuleStatusGet = 1;
       
    58 const TInt KParamSubsession = 3;
       
    59 
       
    60 // ================= MEMBER FUNCTIONS =======================
       
    61 
       
    62 /**
       
    63  * C++ constructor.
       
    64  */
       
    65 CPosSession::CPosSession(CPosServer& aServer,
       
    66                          CPosModuleSettings& aModuleSettings,
       
    67                          CPosModulesStatus& aModulesStatus,
       
    68                          CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub)
       
    69     : iPosServer(aServer),
       
    70       iModuleSettings(aModuleSettings),
       
    71       iModulesStatus(aModulesStatus),
       
    72       iLocMonitorReqHandlerHub(aLocMonitorReqHandlerHub)
       
    73     {      
       
    74     }
       
    75 
       
    76 /**
       
    77  * C++ destructor.
       
    78  */
       
    79 CPosSession::~CPosSession()
       
    80     {
       
    81 
       
    82     delete iSubSessionRegistry;
       
    83     
       
    84     // The flag iServerShutdown prevents calling the server or its members if
       
    85     // it is already destroyed.
       
    86     if (!iServerShutdown)
       
    87         {
       
    88         iModulesStatus.NotifySessionClosed(this); 
       
    89         iLocMonitorReqHandlerHub.NotifySessionClosed( const_cast<const CSession2*>( static_cast<CSession2*> (this) ) ); //TODO ????????????????????????????????????????????
       
    90         
       
    91         if (iDecrementSessions)
       
    92             {
       
    93             iPosServer.DecrementSessions();
       
    94             }
       
    95         }
       
    96     }
       
    97 
       
    98 /**
       
    99  * Two-phased constructor.
       
   100  *
       
   101  * @param aServer Pointer to the server Active Object
       
   102  * @param aModules Modules settings.
       
   103  * @param aModulesStatus Pointer to the ModulesStatus object.
       
   104  * @param aLastPositionHandler Last Position Handler.
       
   105  * @return Pointer to a new instance of CPosSession
       
   106  */
       
   107 CPosSession* CPosSession::NewL(CPosServer& aServer,
       
   108                                CPosModuleSettings& aModuleSettings,
       
   109                                CPosModulesStatus& aModulesStatus,
       
   110                                CPosLocMonitorReqHandlerHub& aLocMonitorReqHandlerHub)
       
   111     {
       
   112     CPosSession* self = new (ELeave)
       
   113         CPosSession(
       
   114             aServer, 
       
   115             aModuleSettings, 
       
   116             aModulesStatus, 
       
   117             aLocMonitorReqHandlerHub);
       
   118             
       
   119     CleanupStack::PushL(self);
       
   120     self->ConstructL();
       
   121     CleanupStack::Pop(self);
       
   122     return self;
       
   123     }
       
   124 
       
   125 /**
       
   126  * Symbian destructor.
       
   127  */
       
   128 void CPosSession::ConstructL()
       
   129     {
       
   130     iSubSessionRegistry = CPosSubsessionRegistry::NewL();
       
   131 
       
   132     // This call will also cancel any server shutdown in progress.
       
   133     iPosServer.IncrementSessions();
       
   134     iDecrementSessions = ETrue;
       
   135 
       
   136     }
       
   137 
       
   138 /**
       
   139  * From CSession2
       
   140  *
       
   141  * This function services all requests from clients.
       
   142  */
       
   143 void CPosSession::ServiceL(const RMessage2& aMessage)
       
   144     {
       
   145     LBSLOG2(ELogP1, "CPosSession::ServiceL function called with Function() = %u\n", aMessage.Function());
       
   146 
       
   147     switch (aMessage.Function())
       
   148         {
       
   149         case ELbsPositionerOpenModuleId:
       
   150 		    OpenFromModuleIdL(aMessage);
       
   151 		    break;
       
   152 	    case ELbsPositionerOpen:
       
   153 		    OpenDefaultPositionerL(aMessage);
       
   154 		    break;
       
   155 	    case ELbsPositionerOpenCriteria:
       
   156 		    OpenPositionerFromCriteriaL(aMessage);
       
   157 		    break;
       
   158 	    case ELbsPositionerClose:
       
   159 		    ClosePositioner(aMessage);
       
   160 		    break;
       
   161 	    case ELbsGetDefaultModuleId:
       
   162 		    GetDefaultModuleIdL(aMessage);
       
   163 		    break;
       
   164 	    case ELbsGetNumModules:
       
   165 		    GetNumModulesL(aMessage);
       
   166 		    break;
       
   167 	    case ELbsGetModuleInfoByIndex:
       
   168 		    GetModuleInfoByIndexL(aMessage);
       
   169 		    break;
       
   170 	    case ELbsGetModuleInfoById:
       
   171 		    GetModuleInfoByIdL(aMessage);
       
   172 		    break;
       
   173 	    case ELbsGetModuleStatus:
       
   174 		    GetModuleStatusL(aMessage);
       
   175 		    break;
       
   176 	    case ELbsNotifyModuleStatusEvent:
       
   177 		    NotifyModuleStatusEventL(aMessage);
       
   178 		    break;
       
   179 	    case ELbsEmptyLastKnownPositionStore:
       
   180 	    	EmptyLastKnownPositionStoreL(aMessage);
       
   181 	    	break;
       
   182 	    case ELbsServerCancelAsyncRequest:
       
   183 			LBS_RDEBUG("Client", "LBS", "CancelAsyncRequest");
       
   184             HandleCancelAsyncRequestL(aMessage);
       
   185 		    break;
       
   186         default:
       
   187             ForwardToSubSessionL(aMessage);
       
   188 		    break;
       
   189         }
       
   190     }
       
   191 
       
   192 /**
       
   193  * From CSession2
       
   194  *
       
   195  * This function is called when ServiceL leaves.
       
   196  */
       
   197 void CPosSession::ServiceError(const RMessage2& aMessage, TInt aError)
       
   198     {
       
   199     DEBUG_TRACE("Client's request failed with error", aError)
       
   200     CSession2::ServiceError(aMessage, aError);
       
   201     }
       
   202 
       
   203 /**
       
   204  * Called when a change has been detected in the location settings. 
       
   205  * @param aEvent Event information
       
   206  */
       
   207 void CPosSession::HandleSettingsChangeL(TPosModulesEvent aEvent)
       
   208     {
       
   209     // For all subSessions, call HandleSettingsChangeL()
       
   210     TInt nrOfSubSessions = iSubSessionRegistry->Count();
       
   211     for (TInt i = 0; i < nrOfSubSessions; i++)
       
   212         {
       
   213         CPosSubSession* subSession = 
       
   214             static_cast <CPosSubSession*> 
       
   215             (iSubSessionRegistry->SubSessionFromIndex(i));
       
   216 		if (subSession)
       
   217 			{
       
   218 			subSession->HandleSettingsChangeL(aEvent);
       
   219 			}
       
   220         }
       
   221     }
       
   222 
       
   223 /**
       
   224  * Called when the server class is shutting down.
       
   225  */
       
   226 void CPosSession::NotifyServerShutdown()
       
   227     {
       
   228     DEBUG_TRACE("NotifyServerShutdown", __LINE__)
       
   229 
       
   230     iServerShutdown = ETrue;
       
   231     TInt nrOfSubSessions = iSubSessionRegistry->Count();
       
   232     
       
   233     iLocMonitorReqHandlerHub.NotifyServerShutDown(); //TODO ????????????????????????????????????????????
       
   234     
       
   235     for (TInt i = 0; i < nrOfSubSessions; i++)
       
   236         {
       
   237         CPosSubSession* subSession = 
       
   238             static_cast <CPosSubSession*> 
       
   239             (iSubSessionRegistry->SubSessionFromIndex(i));
       
   240         if (subSession)
       
   241 			{
       
   242 			subSession->NotifyServerShutdown();
       
   243 			}
       
   244         }
       
   245     }
       
   246 
       
   247 void CPosSession::OpenFromModuleIdL(const RMessage2& aMessage)
       
   248     {
       
   249     DEBUG_TRACE("EPositionerOpenModuleId", __LINE__)
       
   250 
       
   251 	TPckgBuf<TPositionModuleId> moduleIdBuf;
       
   252     User::LeaveIfError(Global::Read(aMessage, KParamModuleIdOpen, moduleIdBuf));
       
   253     CreateSubSessionL(moduleIdBuf(), EFalse, aMessage);
       
   254     RequestComplete(aMessage, KErrNone);
       
   255     }
       
   256 
       
   257 void CPosSession::OpenDefaultPositionerL(const RMessage2& aMessage)
       
   258     {
       
   259     DEBUG_TRACE("EPositionerOpen(Default)", __LINE__)
       
   260     CreateSubSessionL(KPosDefaultModule, ETrue, aMessage);
       
   261 	RequestComplete(aMessage, KErrNone);
       
   262     }
       
   263 
       
   264 void CPosSession::OpenPositionerFromCriteriaL(const RMessage2& aMessage)
       
   265     {
       
   266     DEBUG_TRACE("EPositionerOpenCriteria", __LINE__)
       
   267 
       
   268     // Read Criteria
       
   269 	TPckgBuf<TPositionCriteria> criteria;
       
   270     User::LeaveIfError(Global::Read(aMessage, KParamCriteria, criteria));
       
   271     CreateSubSessionL(KPosStrategyModule, ETrue, aMessage);
       
   272     RequestComplete(aMessage, KErrNone);
       
   273     }
       
   274 
       
   275 void CPosSession::ClosePositioner(const RMessage2& aMessage)
       
   276     {
       
   277     
       
   278     iLocMonitorReqHandlerHub.NotifySubSessionClosed(aMessage);
       
   279     
       
   280     TInt handle = aMessage.Int3();
       
   281     iSubSessionRegistry->CloseSubSession(handle);
       
   282 
       
   283 	RequestComplete(aMessage, KErrNone);
       
   284 
       
   285     DEBUG_TRACE("EPositionerClose", __LINE__)
       
   286     }
       
   287 
       
   288 void CPosSession::GetDefaultModuleIdL(const RMessage2& aMessage)
       
   289     {
       
   290     DEBUG_TRACE("EPositionServerGetDefaultModuleId", __LINE__)
       
   291 
       
   292     CPosModuleIdList* moduleList = iModuleSettings.ModuleIdListL();
       
   293     CleanupStack::PushL( moduleList );
       
   294     TInt nrOfModules = moduleList->Count();
       
   295     TInt res = KErrNotFound;
       
   296 
       
   297     for (TInt i = 0; (i < nrOfModules) && (res == KErrNotFound); i++)
       
   298         {
       
   299         TPositionModuleInfo candidate;
       
   300         iModuleSettings.GetModuleInfoL((*moduleList)[i], candidate);
       
   301 
       
   302         if (candidate.IsAvailable())
       
   303             {
       
   304             TPckg<TPositionModuleId> moduleId(candidate.ModuleId());
       
   305             User::LeaveIfError(Global::Write(aMessage, KParamModuleIdGetDefault, moduleId));
       
   306             res = KErrNone;
       
   307             }
       
   308         }
       
   309 
       
   310     CleanupStack::PopAndDestroy(moduleList);
       
   311     RequestComplete(aMessage, res);
       
   312     }   
       
   313 
       
   314 void CPosSession::GetNumModulesL(const RMessage2& aMessage)
       
   315     {
       
   316     DEBUG_TRACE("EPositionServerGetNumModules", __LINE__)
       
   317 
       
   318     CPosModuleIdList* moduleList = iModuleSettings.ModuleIdListL();
       
   319     TInt num = moduleList->Count();
       
   320     delete moduleList;
       
   321 
       
   322     TPckg<TUint> numPackage(num);
       
   323     User::LeaveIfError(Global::Write(aMessage, KParamNumModules, numPackage));
       
   324     RequestComplete(aMessage, KErrNone);
       
   325     }
       
   326 
       
   327 void CPosSession::GetModuleInfoByIndexL(const RMessage2& aMessage)
       
   328     {
       
   329     DEBUG_TRACE("EPositionServerGetModuleInfoByIndex in", __LINE__)
       
   330 
       
   331     // module index
       
   332     TInt modIndex = aMessage.Int0();
       
   333 
       
   334     CPosModuleIdList* moduleIdList = iModuleSettings.ModuleIdListL();
       
   335     CleanupStack::PushL( moduleIdList );
       
   336     if (modIndex >= moduleIdList->Count() || modIndex < 0)
       
   337         {
       
   338         User::Leave(KErrNotFound);
       
   339         }
       
   340     TPositionModuleId moduleId = (*moduleIdList)[modIndex];
       
   341 
       
   342     // module info
       
   343     HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleInfo);
       
   344 
       
   345     TPositionModuleInfoBase* moduleInfoBase =
       
   346         reinterpret_cast<TPositionModuleInfoBase*>(
       
   347         const_cast<TUint8*>(buffer->Ptr()));
       
   348 
       
   349     Global::ValidatePositionClassBufferL(*moduleInfoBase, buffer->Des());
       
   350     // TPositionModuleInfo is the only class supported by CPosModules
       
   351     Global::ValidatePositionClassTypeL(*moduleInfoBase, EPositionModuleInfoClass);
       
   352     DEBUG_TRACE("Buffer validation done", __LINE__)
       
   353 
       
   354     CleanupStack::PopAndDestroy(2, moduleIdList);
       
   355 
       
   356     // TPositionModuleInfo contains descriptor. If it is corrupt 
       
   357     // (malicious client) then writing to this will panic server
       
   358     // Local instance of TPositionModuleInfo is created to be sure
       
   359     // that module name descriptor is not corrupt
       
   360 
       
   361     TPositionModuleInfo modInfo;
       
   362     iModuleSettings.GetModuleInfoL(moduleId, modInfo);
       
   363 
       
   364     TPckg<TPositionModuleInfo> modInfoPack(modInfo);
       
   365     User::LeaveIfError(Global::Write(aMessage, KParamModuleInfo, modInfoPack));
       
   366 
       
   367     RequestComplete(aMessage, KErrNone);
       
   368     DEBUG_TRACE("EPositionServerGetModuleInfoByIndex out", __LINE__)
       
   369     }
       
   370 
       
   371 void CPosSession::GetModuleInfoByIdL(const RMessage2& aMessage)
       
   372     {
       
   373     DEBUG_TRACE("EPositionServerGetModuleInfoById in", __LINE__)
       
   374 
       
   375     TPckgBuf<TPositionModuleId> moduleIdBuf;
       
   376 	User::LeaveIfError(Global::Read(aMessage, KParamModuleIdGetInfo, moduleIdBuf));
       
   377     TPositionModuleId moduleId = moduleIdBuf();
       
   378 
       
   379     HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleInfo);
       
   380 
       
   381     TPositionModuleInfoBase* moduleInfoBase = 
       
   382 	    reinterpret_cast<TPositionModuleInfoBase*>(
       
   383         const_cast<TUint8*>(buffer->Ptr()));
       
   384 
       
   385     Global::ValidatePositionClassBufferL(*moduleInfoBase, buffer->Des());
       
   386     // TPositionModuleInfo is the only class supported by CPosModules
       
   387     Global::ValidatePositionClassTypeL(*moduleInfoBase, EPositionModuleInfoClass);
       
   388     DEBUG_TRACE("Buffer validation done", __LINE__)
       
   389 
       
   390     CleanupStack::PopAndDestroy(buffer);
       
   391 
       
   392     // TPositionModuleInfo contains descriptor. If it is corrupt 
       
   393     // (malicious client) then writing to this will panic server
       
   394     // Local instance of TPositionModuleInfo is created to be sure
       
   395     // that module name descriptor is not corrupt
       
   396 
       
   397     TPositionModuleInfo modInfo;
       
   398     iModuleSettings.GetModuleInfoL(moduleId, modInfo);
       
   399 
       
   400     TPckg<TPositionModuleInfo> modInfoPack(modInfo);
       
   401     User::LeaveIfError(Global::Write(aMessage, KParamModuleInfo, modInfoPack));
       
   402 
       
   403     RequestComplete(aMessage, KErrNone);
       
   404     DEBUG_TRACE("EPositionServerGetModuleInfoById out", __LINE__)
       
   405     }
       
   406 
       
   407 void CPosSession::GetModuleStatusL(const RMessage2& aMessage)
       
   408     {
       
   409     DEBUG_TRACE("EPositionServerGetModuleStatus in", __LINE__)
       
   410 
       
   411     TPckgBuf<TPositionModuleId> moduleIdBuf;
       
   412 	User::LeaveIfError(Global::Read(aMessage, KParamModuleIdGetStatus, moduleIdBuf));
       
   413     TPositionModuleId moduleId = moduleIdBuf();
       
   414 
       
   415     HBufC8* buffer = Global::CopyClientBuffer8LC(aMessage, KParamModuleStatusGet);
       
   416 
       
   417     // Read module status and write back to client
       
   418     TPositionModuleStatusBase* moduleStatusBase = 
       
   419 	    reinterpret_cast<TPositionModuleStatusBase*>(
       
   420         const_cast<TUint8*>(buffer->Ptr()));
       
   421 
       
   422     Global::ValidatePositionClassBufferL(*moduleStatusBase, buffer->Des());
       
   423 
       
   424     User::LeaveIfError ( 
       
   425         iModulesStatus.GetModuleStatus(moduleId, *moduleStatusBase) );
       
   426     User::LeaveIfError(Global::Write(aMessage, KParamModuleStatusGet, *buffer));
       
   427 
       
   428     CleanupStack::PopAndDestroy(buffer);
       
   429 	RequestComplete(aMessage, KErrNone);
       
   430     DEBUG_TRACE("EPositionServerGetModuleStatus out", __LINE__)
       
   431     }
       
   432 
       
   433 void CPosSession::NotifyModuleStatusEventL(const RMessage2& aMessage)
       
   434     {
       
   435     DEBUG_TRACE("EPositionServerNotifyModuleStatusEvent", __LINE__)
       
   436 
       
   437     iModulesStatus.NotifyModuleStatusEventL(aMessage, this);
       
   438     }
       
   439 
       
   440 void CPosSession::NotifyModuleStatusEventCancelL(const RMessage2& aMessage)
       
   441     {
       
   442     DEBUG_TRACE("EPositionServerNotifyModuleStatusEventCancel", __LINE__)
       
   443 
       
   444     iModulesStatus.CancelNotifyModuleStatusEventL(this);
       
   445     RequestComplete(aMessage, KErrNone);
       
   446     }
       
   447 
       
   448 void CPosSession::HandleCancelAsyncRequestL(const RMessage2& aMessage)
       
   449     {
       
   450     switch (aMessage.Int0())
       
   451         {
       
   452         case KServerNotifyModuleStatusEventSymbian:
       
   453         case KServerNotifyModuleStatusEventVariant:
       
   454         case ELbsNotifyModuleStatusEvent:                 // TODO Verify
       
   455 	        NotifyModuleStatusEventCancelL(aMessage);
       
   456             break;
       
   457         case ELbsEmptyLastKnownPositionStore:
       
   458         	EmptyLastKnownPositionStoreCancelL(aMessage); // TODO Verify
       
   459         
       
   460         default:
       
   461             RequestComplete(aMessage, KErrNotSupported);
       
   462             break;
       
   463         }
       
   464     }
       
   465 
       
   466 void CPosSession::EmptyLastKnownPositionStoreL(const RMessage2& aMessage)
       
   467 	{
       
   468 	
       
   469 	iLocMonitorReqHandlerHub.EmptyLastKnownPosStoreReqL(aMessage);
       
   470 	
       
   471 	}
       
   472 
       
   473 void CPosSession::EmptyLastKnownPositionStoreCancelL(const RMessage2& aMessage)
       
   474 	{
       
   475 	
       
   476 	iLocMonitorReqHandlerHub.CancelEmptyLastKnownPosStoreReqL(aMessage);
       
   477 	
       
   478 	}
       
   479 
       
   480 
       
   481 void CPosSession::CreateSubSessionL(TPositionModuleId aId, TBool aIsProxy, const RMessage2& aMessage)
       
   482 	{
       
   483     CPosSubSession* subSession = CPosSubSession::NewLC(
       
   484         iModuleSettings, 
       
   485         iLocMonitorReqHandlerHub,
       
   486         aId,
       
   487         aIsProxy,
       
   488         &iModulesStatus,
       
   489         &iModulesStatus);
       
   490 
       
   491     TInt subSessionHandle = iSubSessionRegistry->AddInstanceL(subSession);
       
   492     CleanupStack::Pop(subSession); // Now owned by registry
       
   493     
       
   494     // Set the client subsession identifier.
       
   495     TPckg<TInt> handlePackage(subSessionHandle);
       
   496     TInt err = Global::Write(aMessage, KParamSubsession, handlePackage);
       
   497     if (err)
       
   498         {
       
   499         iSubSessionRegistry->CloseSubSession(subSessionHandle);
       
   500         User::Leave(err);
       
   501         }
       
   502     DEBUG_TRACE("Subsession created successfully", __LINE__)
       
   503 	}
       
   504 
       
   505 void CPosSession::ForwardToSubSessionL(const RMessage2& aMessage)
       
   506     {
       
   507     CPosSubSession* subSession =
       
   508         iSubSessionRegistry->SubSessionFromHandleL(aMessage.Int3());
       
   509 
       
   510     if (!subSession)
       
   511 		{
       
   512         User::Leave(KErrNotSupported);
       
   513         }
       
   514 
       
   515     subSession->ServiceL(aMessage); 
       
   516     }
       
   517 
       
   518 void CPosSession::RequestComplete(const RMessage2& aMessage, TInt aCompleteCode)
       
   519     {
       
   520     if (!aMessage.IsNull())
       
   521         {
       
   522         aMessage.Complete(aCompleteCode);
       
   523         }
       
   524     }
       
   525 
       
   526 //  End of File