sysstatemgmt/systemstatemgr/ssm/src/ssmswppolicysrv.cpp
changeset 0 4e1aa6a622a0
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2008-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 // ssmpolicysrv.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32debug.h>
       
    19 #include <e32math.h>
       
    20 #include <f32file.h>
       
    21 #include <s32file.h>
       
    22 #include <ssm/ssmcommandlist.h>
       
    23 
       
    24 #include "ssmswppolicysrv.h"
       
    25 #include "ssmswppolicysess.h"
       
    26 #include "ssmswppolicyconst.h"
       
    27 #include "ssmdebug.h"
       
    28 #include "ssmserverpanic.h"
       
    29 
       
    30 // ------------------- SsmSwpPolicy Server Security Setup ----------------------
       
    31 
       
    32 const TInt KSsmServerSid = 0x2000D75B; //UID3 of sysstatemgr.exe
       
    33 
       
    34 const TUint  KRangeCount = 3;
       
    35 const TInt   KRanges[KRangeCount] =
       
    36 	{
       
    37 	0,
       
    38 	KFirstUsedOpCode,		//range: 1...(EEndOfSsmSwpPolicySrvOpCodes-1) inclusive
       
    39 	EEndOfSsmSwpPolicySrvOpCodes
       
    40 	};
       
    41 
       
    42 /**
       
    43  Maps to index 0 in the array KPolicyElements
       
    44  */
       
    45 const TInt KSsmServerSidCheck = 0;
       
    46 
       
    47 /**
       
    48  Specifies the appropriate action for each range in KRanges.
       
    49  The nth element of KElementsIndex specifies the appropriate action for the nth range in KRanges.
       
    50  */
       
    51 const TUint8 KElementsIndex[KRangeCount] =
       
    52 	{
       
    53 	CPolicyServer::ENotSupported,
       
    54 	KSsmServerSidCheck,
       
    55 	CPolicyServer::ENotSupported,
       
    56 	};
       
    57 
       
    58 /**
       
    59  Array containing the different security checks performed by this server
       
    60  */
       
    61 const CPolicyServer::TPolicyElement KPolicyElements[] =
       
    62 	{
       
    63 	{_INIT_SECURITY_POLICY_S0(KSsmServerSid), CPolicyServer::EFailClient} //lint !e778 suppress Constant expression evaluates to 0 in operation '+'
       
    64 	};
       
    65 
       
    66 /**
       
    67  Setup a security policy which requires all caps to be used by the SsmServer for all requests
       
    68  including creating a connection. The caller's SID is matched against SsmServer's
       
    69  SID in each ServiceL call
       
    70  */
       
    71 const CPolicyServer::TPolicy KSsmSwpPolicyServerPolicy =
       
    72 	{
       
    73 	KSsmServerSidCheck,	// map connection attempts as well to index [0] in KPolicyElements[]
       
    74 	KRangeCount,
       
    75 	KRanges,
       
    76 	KElementsIndex,
       
    77 	KPolicyElements
       
    78 	};
       
    79 
       
    80 /**
       
    81 CSsmSwpPolicyStepCompletion is an active object used for executing all the steps involved in 
       
    82 the swp transition. Initial state for the active object is set as EIdle.
       
    83 */
       
    84 CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion* CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::NewL(MSsmSwpPolicy* aSwpPolicy, CSsmSwpPolicyServer& aServer, const TInt aSessionIndex)
       
    85 	{
       
    86 	CSsmSwpPolicyStepCompletion* self = new(ELeave)CSsmSwpPolicyStepCompletion(aSwpPolicy, aServer, aSessionIndex);
       
    87 	return self;
       
    88 	}
       
    89 
       
    90 CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::CSsmSwpPolicyStepCompletion(MSsmSwpPolicy* aSwpPolicy, CSsmSwpPolicyServer& aServer, const TInt aSessionIndex)
       
    91 	: CActive(EPriorityStandard), iStep(EIdle), iSwpPolicy(aSwpPolicy), iSessionIndex(aSessionIndex), iServer(aServer)
       
    92 	{
       
    93 	CActiveScheduler::Add(this);
       
    94 	}
       
    95 
       
    96 CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::~CSsmSwpPolicyStepCompletion()
       
    97 	{
       
    98 	Cancel();
       
    99 	}
       
   100 
       
   101 /**
       
   102 Calls Initialize of the SwpPolicy. Sets the active object state as EInitialize.
       
   103 */
       
   104 void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::StartInitialize(const RMessagePtr2& aMessagePtr2)
       
   105 	{
       
   106 	__ASSERT_DEBUG(!IsActive(), PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError1));
       
   107 	__ASSERT_DEBUG(iStep == EIdle, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError1));
       
   108 
       
   109 	// This message will be completed in RunL().
       
   110 	iMessagePtr = aMessagePtr2;
       
   111 
       
   112 	// Initialize is the first step in the process of swp transition.
       
   113 	// CSsmSwpPolicyFrame does	all the step checking before giving the request to ssmswppolicyserver 
       
   114 	// so no further checking is required here.
       
   115 	iStep = EInitialize;
       
   116 	iSwpPolicy->Initialize(iStatus);
       
   117 	SetActive();
       
   118 	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
       
   119 	}
       
   120 
       
   121 /**
       
   122 Calls PrepareCommandList of the SwpPolicy. Sets the active object state as EPrepareCommandList.
       
   123 */
       
   124 void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::StartPrepareCommandList(const TSsmSwp& aSwp, const RMessagePtr2& aMessagePtr2)
       
   125 	{
       
   126 	__ASSERT_DEBUG(!IsActive(), PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError2));
       
   127 	__ASSERT_DEBUG(iStep == EInitialize, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError2));
       
   128 
       
   129 	// This message will be completed in RunL().
       
   130 	iMessagePtr = aMessagePtr2;
       
   131 
       
   132 	// PrepareCommandList should be called only after initializing the swp policy.  
       
   133 	// CSsmSwpPolicyFrame does all the step checking before giving the request to ssmswppolicyserver 
       
   134 	// so no further checking is required here.
       
   135 	iStep = EPrepareCommandList;
       
   136 	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
       
   137 	iSwpPolicy->PrepareCommandList(aSwp, iStatus);
       
   138 	SetActive();
       
   139 	}
       
   140 
       
   141 /**
       
   142 Calls HandleCleReturnValue of the SwpPolicy.
       
   143 */
       
   144 void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::StartHandleCleReturnValue(const TSsmSwp& aSwp, TInt aError, TInt aSeverity, const RMessagePtr2& aMessagePtr2)
       
   145 	{
       
   146 	__ASSERT_DEBUG(!IsActive(), PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError4));
       
   147 	__ASSERT_DEBUG(iStep == ECallCommandList, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError4));
       
   148 
       
   149 	// This message will be completed in RunL().
       
   150 	iMessagePtr = aMessagePtr2;
       
   151 
       
   152 	// HandleCleReturnValue should be called only after executing the command list which is returned by swp policy.
       
   153 	// CSsmSwpPolicyFrame does all the step checking before giving the request to ssmswppolicyserver so no further checking is required here.
       
   154 	iStep = EHandleCleReturnValue;
       
   155 	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
       
   156 	iSwpPolicy->HandleCleReturnValue(aSwp, aError, aSeverity, iStatus);
       
   157 	SetActive();
       
   158 	}
       
   159 
       
   160 void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::RunL()
       
   161 	{
       
   162 	DEBUGPRINT2(_L("CSsmSwpPolicyStepCompletion: CSsmSwpPolicyStepCompletion State %d"), iStep);
       
   163 	// Completes the message
       
   164 	iMessagePtr.Complete(iStatus.Int());
       
   165 
       
   166 	// swp transition will be marked as complete only after the execution of HandleCleReturnValue method
       
   167 	if (iStep == EHandleCleReturnValue)
       
   168 		{
       
   169 		// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
       
   170 		// and the same session can be used for the next similar swp transition.
       
   171 		iServer.DeleteSSwpPolicySessionInfo(iSessionIndex);
       
   172 		}
       
   173 	}
       
   174 
       
   175 /**
       
   176 Cancels any outstanding request, based on the state of the active object.
       
   177 */
       
   178 void CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::DoCancel()
       
   179 	{
       
   180 	switch(iStep)
       
   181 		{
       
   182 		case EInitialize:
       
   183 			{
       
   184 			DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: Cancelled the Initization of SwpPolicy"));
       
   185 			iSwpPolicy->InitializeCancel();
       
   186 			iMessagePtr.Complete(KErrCancel);
       
   187 			break;
       
   188 			}
       
   189 		case EPrepareCommandList:
       
   190 			{
       
   191 			DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: Cancelled the Preparation of the commandlist"));
       
   192 			iSwpPolicy->PrepareCommandListCancel();
       
   193 			iMessagePtr.Complete(KErrCancel);
       
   194 			break;
       
   195 			}
       
   196 		case EHandleCleReturnValue:
       
   197 			{
       
   198 			DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: Cancelled the HandleCleReturnValue"));
       
   199 			iSwpPolicy->HandleCleReturnValueCancel();
       
   200 			iMessagePtr.Complete(KErrCancel);
       
   201 			break;
       
   202 			}
       
   203 		default:
       
   204 			{
       
   205 			break;
       
   206 			}
       
   207 		};
       
   208 	}
       
   209 
       
   210 /** 
       
   211 Current RunL() implemenation doesn't leave, so RunError will never be called.
       
   212 */
       
   213 TInt CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::RunError()
       
   214 	{
       
   215 	DEBUGPRINT1(_L("CSsmSwpPolicyStepCompletion: RunError"));
       
   216 	return KErrNone;
       
   217 	}
       
   218 
       
   219 /**
       
   220 Gets the dll handle to SwpPolicy and initializes the SwpPolicy
       
   221 */
       
   222 void CSsmSwpPolicyServer::CallSetDllHandleAndInitializeL(const RMessage2& aMessage, const TInt aSessionIndex)
       
   223 	{
       
   224 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   225 
       
   226 	RLibrary library;
       
   227 	// Sets the swp policy library handle.  Library is owned by the CSsmSwpRequestHandler.
       
   228 	library.SetHandle(aMessage.Int0());
       
   229 
       
   230 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: SwpPolicy handle is set"));
       
   231 	iSessionInfoArray[aSessionIndex].iSwpPolicy = reinterpret_cast<MSsmSwpPolicy*>(library.Lookup(1)());
       
   232 
       
   233 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Create CSsmSwpPolicyStepCompletion active object"));
       
   234 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion = CSsmSwpPolicyStepCompletion::NewL(iSessionInfoArray[aSessionIndex].iSwpPolicy, *this, aSessionIndex);
       
   235 
       
   236 	// aMessage will be completed in CSsmSwpPolicyStepCompletion's RunL method,
       
   237 	// when the Initialization of the swp policy is completed.
       
   238 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->StartInitialize(aMessage);
       
   239 	}
       
   240 
       
   241 /**
       
   242 Cancels the Initialization of the swppolicy, if any Initialization request is pending.
       
   243 */
       
   244 void CSsmSwpPolicyServer::CallInitializeCancel(TInt aSessionIndex)
       
   245 	{
       
   246 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallInitializeCancel"));
       
   247 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   248 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError1));
       
   249 
       
   250 	// CSsmSwpPolicyFrame checks whether initialize is called before cancelling the initialization, , so no need to check
       
   251 	// for valid iSsmSwpPolicyStepCompletion pointer.
       
   252 	// iSessionInfoArray[aSessionIndex].iMessagePtr will be completed in CSsmSwpPolicyStepCompletion's DoCancel method,
       
   253 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->Cancel();
       
   254 	
       
   255 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deleted the session info as Initialize is cancelled"));
       
   256 	// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
       
   257 	// and the same session can be used for the next similar swp transition.
       
   258 	DeleteSSwpPolicySessionInfo(aSessionIndex);
       
   259 	}
       
   260 
       
   261 /**
       
   262 Prepares the commandlist in swppolicy
       
   263 */
       
   264 void CSsmSwpPolicyServer::CallPrepareCommandListL(const RMessage2& aMessage, TInt aSessionIndex)
       
   265 	{
       
   266 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Call SwpPolicy's PrepareCommandList "));
       
   267 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   268 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError2));
       
   269 
       
   270 	TSsmSwp ssmSwp(0,0);
       
   271 	TPckg<TSsmSwp> swpBuf(ssmSwp);
       
   272     aMessage.ReadL(0, swpBuf);
       
   273 
       
   274 	// CSsmSwpPolicyFrame checks whether initialize is called before CallHandleCleReturnValue is called, so no need to check
       
   275 	// for valid iSsmSwpPolicyStepCompletion pointer.
       
   276 
       
   277 	// aMessage will be completed in CSsmSwpPolicyStepCompletion's RunL method,
       
   278 	// when the preparation of the commandlist is completed.
       
   279 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->StartPrepareCommandList(ssmSwp, aMessage);
       
   280 	}
       
   281 
       
   282 /**
       
   283 Cancels the preparation of the commandlist, if any PrepareCommandList request is pending.
       
   284 */
       
   285 void CSsmSwpPolicyServer::CallPrepareCommandListCancel(TInt aSessionIndex)
       
   286 	{
       
   287 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallPrepareCommandListCancel"));
       
   288 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   289 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError3));
       
   290 
       
   291 	// CSsmSwpPolicyFrame checks whether initialize is called before cancelling the initialization, so no need to check
       
   292 	// for valid iSsmSwpPolicyStepCompletion pointer.
       
   293 	// iSessionInfoArray[aSessionIndex].iMessagePtr will be completed in CSsmSwpPolicyStepCompletion's DoCancel method,
       
   294 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->Cancel();
       
   295 	
       
   296 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deleted the session info as PrepareCommandList is cancelled"));
       
   297 	// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
       
   298 	// and the same session can be used for the next similar swp transition.
       
   299 	DeleteSSwpPolicySessionInfo(aSessionIndex);
       
   300 	}
       
   301 
       
   302 /**
       
   303 Returns the commandlist to the client from swppolicy.
       
   304 @return A pointer to commandlist.
       
   305 */
       
   306 void CSsmSwpPolicyServer::CallCommandListL(const RMessage2& aMessage, TInt aSessionIndex)
       
   307 	{
       
   308 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallCommandListL"));
       
   309 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   310 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError4));
       
   311 		// CommandList should be called only after preparing the command list, so the active object state should be EPrepareCommandList.
       
   312 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->CurrentStep() == CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::EPrepareCommandList, 
       
   313 			PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicySrvStepError3));
       
   314 	
       
   315 	// CSsmSwpPolicyFrame checks whether initialize is called before CallCommandList is called, so no need to check
       
   316 	// for valid iSsmSwpPolicyStepCompletion pointer.
       
   317 	// Sets the current step to CallCommandList
       
   318 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->SetCurrentStep(CSsmSwpPolicyServer::CSsmSwpPolicyStepCompletion::ECallCommandList);
       
   319 	CSsmCommandList* ssmCmdList = (iSessionInfoArray[aSessionIndex].iSwpPolicy)->CommandList();
       
   320 	CleanupStack::PushL(ssmCmdList);
       
   321 	CBufFlat* buf = CBufFlat::NewL(KSsmSwpPolicyStreamBufMaxSize);
       
   322 	CleanupStack::PushL(buf);
       
   323 	
       
   324 	RBufWriteStream writeStream(*buf);
       
   325 	CleanupClosePushL(writeStream);
       
   326 	
       
   327 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Externalizes the commandlist"));
       
   328 	ssmCmdList->ExternalizeL(writeStream);
       
   329 
       
   330 	// Ensure any memory that might already have been allocated  is disposed of. 
       
   331 	// Transfer the streamed cmd list from the CBuf.
       
   332 	RBuf8 cmdListBuf;
       
   333 	cmdListBuf.CreateL(buf->Size());
       
   334 	CleanupClosePushL(cmdListBuf);	
       
   335 	buf->Read(0, cmdListBuf);
       
   336 	
       
   337 	aMessage.WriteL(0, cmdListBuf);
       
   338 	
       
   339 	aMessage.Complete(KErrNone);
       
   340 	CleanupStack::PopAndDestroy(4, ssmCmdList);	//	buf, writeStream and cmdListBuf
       
   341 	}
       
   342 
       
   343 /**
       
   344 Handles the value returned by Cle.
       
   345 */
       
   346 void CSsmSwpPolicyServer::CallHandleCleReturnValueL(const RMessage2& aMessage, TInt aSessionIndex)
       
   347 	{
       
   348 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallHandleCleReturnValueL"));
       
   349 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   350 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError5));
       
   351 
       
   352 	TSsmSwp ssmSwp(0,0);
       
   353 	TPckg<TSsmSwp> swpBuf(ssmSwp);
       
   354 	aMessage.ReadL(0, swpBuf);
       
   355 
       
   356 	const TInt error = aMessage.Int1();
       
   357 	const TInt severity = aMessage.Int2();
       
   358 
       
   359 	// CSsmSwpPolicyFrame checks whether initialize is called before CallHandleCleReturnValue is called, so no need to check
       
   360 	// for valid iSsmSwpPolicyStepCompletion pointer.
       
   361 
       
   362 	// aMessage will be completed in CSsmSwpPolicyStepCompletion's RunL method,
       
   363 	// when the cle's return value is handled by the swppolicy.
       
   364 	(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion)->StartHandleCleReturnValue(ssmSwp, error, severity, aMessage);
       
   365 	}
       
   366 
       
   367 /**
       
   368 Cancels the HandleCleReturnValue, if any HandleCleReturnValue request is pending.
       
   369 */
       
   370 void CSsmSwpPolicyServer::CallHandleCleReturnValueCancel(TInt aSessionIndex)
       
   371 	{
       
   372 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: CallHandleCleReturnValueCancel"));
       
   373 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   374 	__ASSERT_DEBUG(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion != NULL, PanicNow(KSsmSwpPolicyServer, ESsmSwpPolicyServerError6));
       
   375 
       
   376 	// CSsmSwpPolicyFrame checks whether initialize is called before cancelling the initialization, so no need to check
       
   377 	// for valid iSsmSwpPolicyStepCompletion pointer.
       
   378 	// iSessionInfoArray[aSessionIndex].iMessagePtr will be completed in CSsmSwpPolicyStepCompletion's DoCancel method.
       
   379 	iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion->Cancel();
       
   380 	
       
   381 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deleted the session info as HandleCleReturnValue is cancelled"));
       
   382 	// In order to avoid the memory leak we have to delete the session info as this swp transition is cancelled, 
       
   383 	// and the same session can be used for the next similar swp transition.
       
   384 	DeleteSSwpPolicySessionInfo(aSessionIndex);
       
   385 	}
       
   386 
       
   387 /**
       
   388 Iterate through iSessionInfoArray to find an unused array element
       
   389 If found, use it. Otherwise, Append() a new SSwpPolicySessionInfo.
       
   390 This function is called during CSession construction.
       
   391 */
       
   392 void CSsmSwpPolicyServer::RegisterSessionL(TInt& aSessionIndex)
       
   393 	{
       
   394 	const TInt count = iSessionInfoArray.Count();
       
   395 	TBool slotFound = EFalse;
       
   396 	
       
   397 	for(TInt i = 0; i < count; ++i)
       
   398 		{
       
   399 		if(!iSessionInfoArray[i].iInUse)
       
   400 			{
       
   401 			DEBUGPRINT1(_L("CSsmSwpPolicyServer: Using the free slot of the sessionarray"));
       
   402 			iSessionInfoArray[i].iInUse = ETrue;
       
   403 			__ASSERT_ALWAYS(NULL, iSessionInfoArray[i].iSwpPolicy);
       
   404 			aSessionIndex = i;
       
   405 			slotFound = ETrue;
       
   406 			break;
       
   407 			}
       
   408 		}
       
   409 	
       
   410 	if(!slotFound)
       
   411 		{
       
   412 		DEBUGPRINT1(_L("CSsmSwpPolicyServer: No free slot found, so appending a new member to the sessionarray"));
       
   413 		SSwpPolicySessionInfo sessionInfo;
       
   414 		sessionInfo.iInUse = ETrue;
       
   415 		sessionInfo.iSwpPolicy = NULL;
       
   416 		sessionInfo.iSsmSwpPolicyStepCompletion = NULL;
       
   417 		iSessionInfoArray.AppendL(sessionInfo);
       
   418 		// using count instead of iSessionInfoArray.Count()-1 as it is set before appending the element to the array,
       
   419 		// and its value is equal to iSessionInfoArray.Count()-1
       
   420 		aSessionIndex = count;
       
   421 		}
       
   422 	DEBUGPRINT2(_L("Registered SsmSwpPolicyCli in slot %d"), aSessionIndex);
       
   423 	}
       
   424 
       
   425 /**
       
   426 This method is used to delete the session information once the swp transition is complete.
       
   427 This is required as the same session can be used for more than one individual swp transition.
       
   428 */
       
   429 void CSsmSwpPolicyServer::DeleteSSwpPolicySessionInfo(TInt aSessionIndex)
       
   430 	{
       
   431 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   432 
       
   433 	DEBUGPRINT1(_L("CSsmSwpPolicyServer: Deletes the SwpPolicySession information."));
       
   434 	if(iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion)
       
   435 		{
       
   436 		delete iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion;
       
   437 		iSessionInfoArray[aSessionIndex].iSsmSwpPolicyStepCompletion = NULL;
       
   438 		}
       
   439 
       
   440 	if(iSessionInfoArray[aSessionIndex].iSwpPolicy)
       
   441 		{
       
   442 		DEBUGPRINT1(_L("CSsmSwpPolicyServer: Releases the SwpPolicy"));
       
   443 		(iSessionInfoArray[aSessionIndex].iSwpPolicy)->Release();
       
   444 		iSessionInfoArray[aSessionIndex].iSwpPolicy = NULL;
       
   445 		}
       
   446 	}
       
   447 
       
   448 /**
       
   449 Called from CSession destructor.
       
   450 */
       
   451 void CSsmSwpPolicyServer::DeregisterSession(const TInt& aSessionIndex)
       
   452 	{
       
   453 	__ASSERT_DEBUG(IN_RANGE(aSessionIndex, iSessionInfoArray.Count()), PanicNow(KSsmSwpPolicyBadIdx, KSsmSwpPolicySrvArrayIndexInvalid));
       
   454 	
       
   455 	DeleteSSwpPolicySessionInfo(aSessionIndex);
       
   456 	iSessionInfoArray[aSessionIndex].iInUse = EFalse;
       
   457 
       
   458 	// Remove unused elements at the end of the array, so iSessionInfoArray can be (granular) shrunk 
       
   459     const TInt count = iSessionInfoArray.Count(); 
       
   460     TBool slotRemoved = EFalse; 
       
   461     for (TInt i = count-1; i >= 0 ; i--) 
       
   462          {
       
   463         if (!iSessionInfoArray[i].iInUse) 
       
   464         	{
       
   465             iSessionInfoArray.Remove(i); 
       
   466             slotRemoved = ETrue; 
       
   467         	}
       
   468         else 
       
   469         	{
       
   470         	break;
       
   471         	}
       
   472          } 
       
   473 	   if (slotRemoved) 
       
   474 		   { 
       
   475 		   iSessionInfoArray.GranularCompress(); 
       
   476 		   } 
       
   477 	DEBUGPRINT2(_L("De-registered SsmSwpPolicyCli slot %d"), aSessionIndex);
       
   478  	}
       
   479 
       
   480 /**
       
   481 Used to create a new server-side session.
       
   482 @return A pointer to the new instance of CSession2.
       
   483 @leave KErrNotSupported if versions are incompatible.
       
   484 */
       
   485 EXPORT_C CSession2* CSsmSwpPolicyServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
       
   486 	{
       
   487 	TVersion version(KSsmSwpPolicySrvVersionMajor, KSsmSwpPolicySrvVersionMinor, KSsmSwpPolicySrvVersionBuild);
       
   488 
       
   489 	if(!User::QueryVersionSupported(version, aVersion))
       
   490 		{
       
   491 		DEBUGPRINT1(_L("CSsmSwpPolicyServer: Server version not supported"));
       
   492 		User::Leave(KErrNotSupported);
       
   493 		}
       
   494 
       
   495 	CSsmSwpPolicyServer& mutatedSelf = const_cast< CSsmSwpPolicyServer& >(*this);
       
   496 	return CSsmSwpPolicySession::NewL(mutatedSelf); 
       
   497 	}
       
   498 	
       
   499 /**
       
   500 Used to create a new CSsmSwpPolicyServer
       
   501 @return A pointer to the CSsmSwpPolicyServer
       
   502 */
       
   503 CSsmSwpPolicyServer* CSsmSwpPolicyServer::NewLC(const TDesC& aServerName)
       
   504 	{
       
   505 	CSsmSwpPolicyServer* self = new(ELeave) CSsmSwpPolicyServer;	
       
   506 	CleanupStack::PushL(self);
       
   507 	self->ConstructL(aServerName);
       
   508 	return self;	
       
   509 	}
       
   510 
       
   511 /**
       
   512 Static function used to create and start CSsmSwpPolicyServer
       
   513 @return KErrAlreadyExists if the server is already running
       
   514 */
       
   515 EXPORT_C TInt CSsmSwpPolicyServer::StartSsmSwpPolicySrv(const TDesC& aServerName)
       
   516 	{
       
   517 	TAny* threadParam = reinterpret_cast<TAny*>(const_cast<TDesC*>(&aServerName));
       
   518 
       
   519 	// Create a Unique name for the thread name
       
   520 	TName name(aServerName);
       
   521 	_LIT(KUnderScore, "_");
       
   522 	name.Append(KUnderScore);
       
   523 	name.AppendNum(Math::Random(), EHex);
       
   524 
       
   525 	const TInt KSsmPolicySrvMinHeapSize = 0x2000;	// 8kB
       
   526 	const TInt KSsmPolicySrvMaxHeapSize = 10 * KSsmPolicySrvMinHeapSize;
       
   527 	RThread srvThread;
       
   528 	TInt err = srvThread.Create(name, &CSsmSwpPolicyServer::SsmSwpPolicySrvThreadFn, 
       
   529 								 KDefaultStackSize, KSsmPolicySrvMinHeapSize, KSsmPolicySrvMaxHeapSize, 
       
   530 								 threadParam, EOwnerProcess);
       
   531 
       
   532 	DEBUGPRINT2(_L("CSsmSwpPolicyServer: SsmSwpPolicyServer created with %d") ,err);
       
   533 	if(KErrNone == err)
       
   534 		{
       
   535 		TRequestStatus trs;
       
   536 	
       
   537 		srvThread.Rendezvous(trs);
       
   538 		srvThread.Resume();
       
   539 		
       
   540 		User::WaitForRequest(trs);	
       
   541 		err = trs.Int();
       
   542 		srvThread.Close();
       
   543 		}
       
   544 
       
   545 	return err;
       
   546 	}
       
   547 
       
   548 /**
       
   549 Creates the ssmSwpPolicyServer
       
   550 */
       
   551 TInt CSsmSwpPolicyServer::SsmSwpPolicySrvThreadFn(TAny* aAny)
       
   552 	{
       
   553 	const TDesC* serverName = const_cast<const TDesC*>(static_cast<TDesC*>(aAny));
       
   554 	TInt err = KErrNoMemory;
       
   555     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   556     if(cleanup)
       
   557     	{
       
   558 	    TRAP(err,
       
   559 	        {
       
   560 	        CActiveScheduler* sched = new(ELeave) CActiveScheduler();
       
   561 	        CleanupStack::PushL(sched);
       
   562 	        CActiveScheduler::Install(sched);
       
   563 	
       
   564 	        CSsmSwpPolicyServer* ssmSwpPolicySrv = CSsmSwpPolicyServer::NewLC(*serverName);
       
   565 	        RThread::Rendezvous(KErrNone);
       
   566 	    	// Must not use serverName after rendezvousing with client
       
   567 	        serverName = NULL;
       
   568 	        
       
   569 	        CActiveScheduler::Start();
       
   570 	
       
   571 	        CleanupStack::PopAndDestroy(ssmSwpPolicySrv);
       
   572 	        CleanupStack::PopAndDestroy(sched);
       
   573 	        });
       
   574 
       
   575 	    delete cleanup;
       
   576     	}
       
   577  
       
   578     return err;
       
   579 	}
       
   580 
       
   581 CSsmSwpPolicyServer::CSsmSwpPolicyServer()
       
   582 	: CPolicyServer(EPriorityHigh, KSsmSwpPolicyServerPolicy, EUnsharableSessions)
       
   583 	{
       
   584 	}
       
   585 
       
   586 /**
       
   587 Starts the ssmSwpPolicyServer
       
   588 */
       
   589 void CSsmSwpPolicyServer::ConstructL(const TDesC& aServerName)
       
   590 	{
       
   591 	StartL(aServerName);
       
   592 	// The starting thread is signalled in the thread function.
       
   593 	}
       
   594 
       
   595 CSsmSwpPolicyServer::~CSsmSwpPolicyServer()
       
   596 	{
       
   597 	iSessionInfoArray.Close();
       
   598 	}
       
   599