pimprotocols/phonebooksync/Server/phbksyncsvr.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 // Copyright (c) 2002-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 // Implementation of the CPhoneBookServer class which is the front-end server,
       
    15 // responsible for processing all short and quick requests, and for passing
       
    16 // longer requests to the engine.
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file
       
    22  @internalComponent
       
    23 */
       
    24 
       
    25 #include <connect/sbdefs.h>
       
    26 #include <commsdattypesv1_1.h>
       
    27 #include <cdblen.h>
       
    28 
       
    29 #include "common.h"
       
    30 #include "PhonebookManager.h"
       
    31 #include "SyncContactICCEntry.h"
       
    32 #include "phbksynclog.h"
       
    33 #include "phbksyncsvr.h"
       
    34 #include "phbksyncsess.h"
       
    35 #include "SyncEngineRequest.h"
       
    36 #include "ActiveNotifications.h"
       
    37 
       
    38 
       
    39 using namespace CommsDat;
       
    40 
       
    41 
       
    42 /**
       
    43  * Number of retries for connecting to Etel.
       
    44  */
       
    45 const TInt KMaxConnectToEtelRetries = 3;
       
    46 
       
    47 
       
    48 //
       
    49 //  Definition of iPolicy dictating the capability checking for phbksyncsvr...
       
    50 //
       
    51 const TUint iRangeCount = 10;
       
    52 
       
    53 const TInt CPhoneBookServer::iRanges[iRangeCount] = 
       
    54 	{
       
    55 	0,		//range is 0
       
    56 	1,		//range is 1-3 inclusive
       
    57 	4,		//range is 4-5 inclusive
       
    58 	6,		//range is 6
       
    59 	7,		//range is 7-13 inclusive
       
    60 	14,		//range is 14
       
    61 	15,		//range is 15-16 inclusive
       
    62 	17,		//range is 17-24 inclusive
       
    63 	25,		//range is 25 inclusive
       
    64 	26,		//range is 26-KMaxTInt inclusive
       
    65 	};
       
    66 
       
    67 const TUint8 CPhoneBookServer::iElementsIndex[iRangeCount] = 
       
    68 	{
       
    69 	0,
       
    70 	1,
       
    71 	2,
       
    72 	3,
       
    73 	4,
       
    74 	5,
       
    75 	6,
       
    76 	7,
       
    77 	8,
       
    78 	CPolicyServer::ENotSupported,
       
    79 	};
       
    80 
       
    81 const CPolicyServer::TPolicyElement CPhoneBookServer::iElements[] = 
       
    82 	{
       
    83 	{ _INIT_SECURITY_POLICY_C2( ECapabilityReadUserData, ECapabilityWriteUserData), CPolicyServer::EFailClient},	// policy 0:  range 0 - 0
       
    84 	{ _INIT_SECURITY_POLICY_C1( ECapability_None), CPolicyServer::EFailClient},	// policy 1:  range 1 - 3
       
    85 	{ _INIT_SECURITY_POLICY_C1( ECapabilityWriteUserData), CPolicyServer::EFailClient},	// policy 2:  range 4 - 5
       
    86 	{ _INIT_SECURITY_POLICY_C1( ECapabilityReadUserData), CPolicyServer::EFailClient},	// policy 3:  range 6 - 6
       
    87 	{ _INIT_SECURITY_POLICY_C1( ECapability_None), CPolicyServer::EFailClient},	// policy 4:  range 7 - 13
       
    88 	{ _INIT_SECURITY_POLICY_C2( ECapabilityReadUserData, ECapabilityWriteUserData), CPolicyServer::EFailClient},	// policy 5:  range 14 - 14
       
    89 	{ _INIT_SECURITY_POLICY_C1( ECapabilityWriteUserData), CPolicyServer::EFailClient},	// policy 6:  range 15 - 16
       
    90 	{ _INIT_SECURITY_POLICY_C1( ECapability_None), CPolicyServer::EFailClient},	// policy 7:  range 17 - 24
       
    91 #ifdef _DEBUG
       
    92 	{ _INIT_SECURITY_POLICY_C1( ECapability_None), CPolicyServer::EFailClient}, // policy 8: range 25
       
    93 #else
       
    94 	{ _INIT_SECURITY_POLICY_FAIL}, // policy 8: range 25
       
    95 #endif
       
    96 	};
       
    97 
       
    98 const CPolicyServer::TPolicy CPhoneBookServer::iPolicy = 
       
    99 	{
       
   100 	CPolicyServer::EAlwaysPass,
       
   101 	iRangeCount,
       
   102 	iRanges,
       
   103 	iElementsIndex,
       
   104 	iElements
       
   105 	};
       
   106 
       
   107 
       
   108 /**
       
   109  *  Static factory method used to create a CPhoneBookServer object.
       
   110  *
       
   111  *  @return  Pointer to the created CPhoneBookServer object, or NULL.
       
   112  */
       
   113 CPhoneBookServer* CPhoneBookServer::NewL()
       
   114 	{
       
   115 	LOGSERVER1(_L8("NewL()"));
       
   116 	CPhoneBookServer* self = new (ELeave) CPhoneBookServer();
       
   117 	CleanupStack::PushL(self);
       
   118 	self->ConstructL();
       
   119 	CleanupStack::Pop(self);
       
   120 
       
   121 	return self;
       
   122 	} // CPhoneBookServer::NewL
       
   123 
       
   124 
       
   125 /**
       
   126  *  Standard constructor.
       
   127  */
       
   128 CPhoneBookServer::CPhoneBookServer()
       
   129 	: CPolicyServer(EPriorityNormal, iPolicy, ESharableSessions), 
       
   130 	iServerConfigLevel(EServerConfigurationNone),
       
   131 	iICCCaps(RMobilePhone::KCapsSimAccessSupported), 
       
   132 	iPhonebookManager(NULL),
       
   133 	iShouldShutdownServer(EFalse),
       
   134 	iShouldShutdownUnconditionally(EFalse)
       
   135 	{
       
   136 	__DECLARE_NAME(_L("CPhoneBookServer"));
       
   137 	} // CPhoneBookServer::CPhoneBookServer
       
   138 
       
   139 
       
   140 /**
       
   141  *  Second phase constructor. Ensures the server is created and ready to run.
       
   142  */
       
   143 void CPhoneBookServer::ConstructL()
       
   144 	{
       
   145 	StartL(PHBKSYNC_SERVER_NAME);
       
   146 	} // CPhoneBookServer::ConstructL
       
   147 
       
   148 
       
   149 /**
       
   150  *  Destructor.
       
   151  */
       
   152 CPhoneBookServer::~CPhoneBookServer()
       
   153 	{
       
   154 	//
       
   155 	// Stop the server from starting if it has initiated a startup.
       
   156 	//
       
   157 	delete iPhoneBookSyncStarter;
       
   158 	iPhoneBookSyncStarter = NULL;
       
   159 	
       
   160 	//
       
   161 	// Unconfigure the server if needed...
       
   162 	//
       
   163 	TRAP_IGNORE(ConfigureServerL(EServerConfigurationNone));
       
   164 
       
   165 	iCacheStateNotificationArray.Reset();
       
   166 	iSyncEngineRequestArray.ResetAndDestroy();
       
   167 	iSessionArray.Reset();
       
   168 	} // CPhoneBookServer::~CPhoneBookServer
       
   169 
       
   170 
       
   171 /**
       
   172  *  Attempts to configure or unconfigure the server as specified. If this
       
   173  *  function leaves, the configuration state will be invalid. This function
       
   174  *  is therefore a private function and callers should use ConfigureServerL()
       
   175  *  instead which protects against such problems.
       
   176  *  
       
   177  *  @param aLevel  The desired configuration level to initialise the server to.
       
   178  */
       
   179 void CPhoneBookServer::AttemptToConfigureServerL(TServerConfiguration aLevel)
       
   180 	{
       
   181 	LOGSERVER2(_L8("AttemptToConfigureServerL() to level %d"), aLevel);
       
   182 
       
   183 	//
       
   184 	// Are we configuring or unconfiguring?
       
   185 	//
       
   186 	if (iServerConfigLevel < aLevel)
       
   187 		{
       
   188 		//
       
   189 		// Configure from level 'None' to 'Idle'...
       
   190 		//
       
   191 		if (iServerConfigLevel == EServerConfigurationNone)
       
   192 			{
       
   193 			iServerConfigLevel = EServerConfigurationConfiguringToIdle;
       
   194 			LOGSERVER1(_L8("Configuration changed from 'None' to 'ConfiguringToIdle'."));
       
   195 
       
   196 			iNotifyBackupAndRestore = CNotifyBackupAndRestore::NewL(*this);
       
   197 			User::LeaveIfError(iNotifyBackupAndRestore->Start());
       
   198 
       
   199 			iServerConfigLevel = EServerConfigurationIdle;
       
   200 			LOGSERVER1(_L8("Configuration changed from 'ConfiguringToIdle' to 'Idle'."));
       
   201 			}
       
   202 
       
   203 		//
       
   204 		// Configure from level 'Idle' to 'Full'...
       
   205 		//
       
   206 		if (iServerConfigLevel < aLevel  &&
       
   207 			iServerConfigLevel == EServerConfigurationIdle)
       
   208 			{
       
   209 			iServerConfigLevel = EServerConfigurationConfiguringToFull;
       
   210 			LOGSERVER1(_L8("Configuration changed from 'Idle' to 'ConfiguringToFull'."));
       
   211 
       
   212 			//
       
   213 			// Connect to ETel...
       
   214 			//
       
   215 			TInt  etelErr(KErrNone), retryCount;
       
   216 
       
   217    			for (retryCount = 0;  retryCount < KMaxConnectToEtelRetries;  retryCount++)
       
   218    				{
       
   219    				TRAP(etelErr, ConnectToEtelL());	//This can leave due to a denied access 										
       
   220 													//to CommDb or Etel
       
   221    				if (etelErr == KErrNone)
       
   222 					{
       
   223    					break;
       
   224 					}
       
   225 
       
   226 				if (retryCount < KMaxConnectToEtelRetries - 1)
       
   227 					{
       
   228    					User::After(1000000);
       
   229 					}
       
   230    				}
       
   231    			User::LeaveIfError(etelErr);
       
   232 
       
   233 			//
       
   234 			// Setup the phonebook parameters and create the Phonebook Manager.
       
   235 			// This will also read the settings from the INI file.
       
   236 			//
       
   237 			if (iPhone.GetIccAccessCaps(iICCCaps) != KErrNone)
       
   238 				{
       
   239 				iICCCaps = RMobilePhone::KCapsSimAccessSupported;
       
   240 				}
       
   241 
       
   242 			iPhonebookManager = CPhoneBookManager::NewL(iICCCaps);
       
   243 
       
   244 			//
       
   245 			// Initialise and start the Active Objects...
       
   246 			//
       
   247 			iGetPhoneStoreInfo = CGetPhoneStoreInfo::NewL(*this,
       
   248 														  *iPhonebookManager,
       
   249 														  iPhone);
       
   250 			User::LeaveIfError(iGetPhoneStoreInfo->Start());
       
   251 
       
   252 			iNotifyLockInfoChange = CNotifyLockInfoChange::NewL(*this, iPhone);
       
   253 			User::LeaveIfError(iNotifyLockInfoChange->Start());
       
   254 
       
   255 			iGetSecurityEvent = CNotifySecurityEvent::NewL(*this, iPhone);
       
   256 			User::LeaveIfError(iGetSecurityEvent->Start());
       
   257 
       
   258 			if (IsUsimAppTsy()  &&
       
   259 				(iICCCaps & RMobilePhone::KCapsUSimAccessSupported))
       
   260 				{
       
   261 				iNotifyAppInfoChange = CNotifyAppInfoChange::NewL(*this, iPhone);
       
   262 				User::LeaveIfError(iNotifyAppInfoChange->Start());
       
   263 				}
       
   264 
       
   265 			if (iIsSatSupported)
       
   266 				{
       
   267 				iNotifySatUpdates = CNotifySATUpdates::NewL(*this, iSat);
       
   268 	 			User::LeaveIfError(iNotifySatUpdates->Start());
       
   269 				}
       
   270 
       
   271 			//
       
   272 			// Start the Sync Engine...
       
   273 			//
       
   274 			User::LeaveIfError(iSyncEngine.Connect(iPhonebookManager));
       
   275 
       
   276 			iServerConfigLevel = EServerConfigurationFull;
       
   277 			LOGSERVER1(_L8("Configuration changed from 'ConfiguringToFull' to 'Full'."));
       
   278 			}
       
   279 		}
       
   280 	else if (iServerConfigLevel > aLevel)
       
   281 		{
       
   282 		//
       
   283 		// Unconfigure from level 'Full' to 'Idle'...
       
   284 		//
       
   285 		if (iServerConfigLevel == EServerConfigurationFull  ||
       
   286 			iServerConfigLevel == EServerConfigurationConfiguringToFull)
       
   287 			{
       
   288 			iCacheStateNotificationArray.Reset();
       
   289 			iSyncEngineRequestArray.ResetAndDestroy();
       
   290 
       
   291 			iSyncEngine.Close();
       
   292 
       
   293 			delete iNotifySatUpdates;
       
   294 			iNotifySatUpdates = NULL;
       
   295 
       
   296 			delete iGetSecurityEvent;
       
   297 			iGetSecurityEvent = NULL;
       
   298 
       
   299 			delete iNotifyLockInfoChange;
       
   300 			iNotifyLockInfoChange = NULL;
       
   301 
       
   302 			delete iGetPhoneStoreInfo;
       
   303 			iGetPhoneStoreInfo = NULL;
       
   304 
       
   305 			delete iPhonebookManager;
       
   306 			iPhonebookManager = NULL;
       
   307 
       
   308 			delete iNotifyAppInfoChange;
       
   309 			iNotifyAppInfoChange = NULL;
       
   310 
       
   311 			iSat.Close();
       
   312 			iPhone.Close();
       
   313 			iEtelServer.Close();
       
   314 				
       
   315 			iServerConfigLevel = EServerConfigurationIdle;
       
   316 			LOGSERVER1(_L8("Configuration changed to 'Idle'."));
       
   317 			}
       
   318 		//
       
   319 		// Unconfigure from level 'Idle' to 'None'...
       
   320 		//
       
   321 		if (iServerConfigLevel > aLevel  &&
       
   322 			(iServerConfigLevel == EServerConfigurationIdle  ||
       
   323 			 iServerConfigLevel == EServerConfigurationConfiguringToIdle))
       
   324 			{
       
   325 			delete iNotifyBackupAndRestore;
       
   326 			iNotifyBackupAndRestore = NULL;
       
   327 
       
   328 			iServerConfigLevel = EServerConfigurationNone;
       
   329 			LOGSERVER1(_L8("Configuration changed to 'None'."));
       
   330 			}
       
   331 		}
       
   332 	} // CPhoneBookServer::AttemptToConfigureServerL
       
   333 
       
   334 
       
   335 /**
       
   336  *  Configures or unconfigures the server as specified.
       
   337  *  
       
   338  *  @param aLevel  The desired configuration level to initialise the server to.
       
   339  */
       
   340 void CPhoneBookServer::ConfigureServerL(TServerConfiguration aLevel)
       
   341 	{
       
   342 	//
       
   343 	// Check parameter is valid...
       
   344 	//
       
   345 	if (aLevel != EServerConfigurationNone  &&
       
   346 		aLevel != EServerConfigurationIdle  &&
       
   347 		aLevel != EServerConfigurationFull)
       
   348 		{
       
   349 		User::Leave(KErrArgument);
       
   350 		}
       
   351 
       
   352 	//
       
   353 	// Save the current configuration level in case AttemptToConfigureServerL()
       
   354 	// leaves.
       
   355 	//
       
   356 	TServerConfiguration  oldConfigLevel = iServerConfigLevel;
       
   357 
       
   358 	TRAPD(configErr, AttemptToConfigureServerL(aLevel));
       
   359 
       
   360 	//
       
   361 	// If the attempt to configure the server failed, then reset the config
       
   362 	// state and leave.
       
   363 	//
       
   364 	if (configErr != KErrNone)
       
   365 		{
       
   366 		LOGSERVER2(_L8("ConfigureServerL: Could not config server (Error %d)."),
       
   367 			     configErr);
       
   368 
       
   369 		TRAPD(unconfigErr, AttemptToConfigureServerL(oldConfigLevel));
       
   370 		if (unconfigErr != KErrNone)
       
   371 			{
       
   372 			LOGSERVER2(_L8("ConfigureServerL: Could not unconfig server either (Error %d)."),
       
   373 				     unconfigErr);
       
   374 			}
       
   375 
       
   376 		iServerConfigLevel = oldConfigLevel;
       
   377 
       
   378 		User::Leave(configErr);
       
   379 		}
       
   380 	} // CPhoneBookServer::ConfigureServerL
       
   381 
       
   382 
       
   383 /**
       
   384  *  This method is called by the system to indicate that a backup or restore has
       
   385  *  started.
       
   386  */
       
   387 void CPhoneBookServer::HandleBackupOrRestoreStarting()
       
   388 	{
       
   389 	LOGSERVER1(_L8("HandleBackupOrRestoreStarting()"));
       
   390 
       
   391 	TRAPD(err, ConfigureServerL(EServerConfigurationIdle));
       
   392 	if (err != KErrNone)
       
   393 		{
       
   394 		LOGSERVER2(_L8("ConfigureServerL() failed with error %d."), err);
       
   395 		}
       
   396 	} // CPhoneBookServer::HandleBackupOrRestoreStarting
       
   397 
       
   398 
       
   399 /**
       
   400  *  This method is called by the system to indicate that a backup or restore has
       
   401  *  completed.
       
   402  */
       
   403 void CPhoneBookServer::HandleBackupOrRestoreComplete()
       
   404 	{
       
   405 	LOGSERVER1(_L8("HandleBackupOrRestoreComplete()"));
       
   406 
       
   407 	TRAPD(err, ConfigureServerL(EServerConfigurationFull));
       
   408 	if (err != KErrNone)
       
   409 		{
       
   410 		LOGSERVER2(_L8("ConfigureServerL() failed with error %d."), err);
       
   411 		}
       
   412 	} // CPhoneBookServer::HandleBackupOrRestoreComplete
       
   413 
       
   414 
       
   415 /**
       
   416  *  Create a new client session.
       
   417  *
       
   418  *  @note You can not create a new session if the server is shuting down
       
   419  *        unconditionally.
       
   420  */
       
   421 CSession2* CPhoneBookServer::NewSessionL(const TVersion&, const RMessage2& /*aMessage*/) const
       
   422 	{
       
   423 	LOGSERVER1(_L8("NewSessionL"));
       
   424 
       
   425 	if (iShouldShutdownUnconditionally)
       
   426 		{
       
   427 		User::Leave(KErrPermissionDenied);
       
   428 		}
       
   429 
       
   430 	return new(ELeave) CPhoneBookSession();
       
   431 	} // CPhoneBookServer::NewSessionL
       
   432 
       
   433 
       
   434 /**
       
   435  *  Called by the session class when it is being created.
       
   436  *
       
   437  *  @param aSession  Server side session.
       
   438  */
       
   439 void CPhoneBookServer::AddSessionL(CPhoneBookSession* aSession)
       
   440 	{
       
   441 	LOGSERVER1(_L8("AddSession"));
       
   442 
       
   443 	//
       
   444 	// Store this session in the list of sessions...
       
   445 	//
       
   446 	iSessionArray.Append(aSession);
       
   447 
       
   448 	//
       
   449 	// Queue an Active Object to configure the server straight after this
       
   450 	// session is created.
       
   451 	//
       
   452 	if (iPhoneBookSyncStarter == NULL  &&
       
   453 	    iServerConfigLevel == EServerConfigurationNone)
       
   454 		{
       
   455 		iPhoneBookSyncStarter = new (ELeave) CPhoneBookSyncStarter(*this);
       
   456 		iPhoneBookSyncStarter->Call();
       
   457 		}
       
   458 	} // CPhoneBookServer::AddSessionL
       
   459 
       
   460 
       
   461 /**
       
   462  *  Called by the session class when it is being destroyed.
       
   463  *
       
   464  *  @param aSession  Server side session.
       
   465  */
       
   466 void CPhoneBookServer::DropSession(CPhoneBookSession* aSession)
       
   467 	{
       
   468 	LOGSERVER1(_L8("DropSession"));
       
   469 
       
   470 	//
       
   471 	// Remove this session from the session array list...
       
   472 	//
       
   473 	TInt  position;
       
   474 	
       
   475 	position = iSessionArray.Find(aSession);
       
   476  	if (position != KErrNotFound) 
       
   477 		{
       
   478  		iSessionArray.Remove(position);
       
   479  		
       
   480  		// 
       
   481  		// Also remove any outstanding notifications owned by this session
       
   482  		//
       
   483 		for (TInt index = 0;  index < iCacheStateNotificationArray.Count();  index++)
       
   484 			{
       
   485 			TCacheStateNotification  notifyRequest = iCacheStateNotificationArray[index];
       
   486 
       
   487 			if (notifyRequest.iSession == aSession)
       
   488 				{
       
   489 				//
       
   490 				// If it is in the list then just remove and complete it since session has been closed...
       
   491 				//
       
   492 				aSession->CompleteRequest(notifyRequest.iMessage, KErrDisconnected);
       
   493 				iCacheStateNotificationArray.Remove(index);
       
   494 				index--;
       
   495 				}
       
   496 			} 		
       
   497 		}
       
   498 
       
   499 	//
       
   500 	// If we are shuting down then unconfigure and stop...
       
   501 	//
       
   502 	if (iSessionArray.Count() == 0  &&  iShouldShutdownServer)
       
   503 		{
       
   504 		TRAP_IGNORE(ConfigureServerL(EServerConfigurationNone));
       
   505 		CActiveScheduler::Stop();
       
   506 		}
       
   507 	} // CPhoneBookServer::DropSession
       
   508 
       
   509 
       
   510 /**
       
   511  *  Requests a synchronisation from the engine. This is an asynchronous
       
   512  *  request that will result in an engine request being posted to the engine.
       
   513  *
       
   514  *  @param aSession       A reference to the client session.
       
   515  *  @param aMessage       A reference to the client request.
       
   516  *  @param aPhonebookUid  UID of the ICC phonebook to perform the operation on.
       
   517  */
       
   518 void CPhoneBookServer::DoSynchronisationL(CPhoneBookSession& aSession,
       
   519 										  const RMessage2& aMessage,
       
   520 										  TUid aPhonebookUid)
       
   521 	{
       
   522 	LOGSERVER2(_L8("DoSynchronisationL(0x%08x)"), aPhonebookUid);
       
   523 
       
   524 	//
       
   525 	// Is the server configured for use?
       
   526 	//
       
   527 	if (iServerConfigLevel != EServerConfigurationFull)
       
   528 		{
       
   529 		aSession.CompleteRequest(aMessage, KErrNotReady);
       
   530 		return;
       
   531 		}
       
   532 
       
   533 	//
       
   534 	// Validate the phonebook UID to ensure sync requests can only be posted
       
   535 	// for valid phonebooks. Although no harm would come of sending the engine
       
   536 	// a sync request with an invalid UID (it will check it as well) we can
       
   537 	// easily check it now, and reduce the load on the engine.
       
   538 	//
       
   539 	if (iPhonebookManager->ValidatePhonebookUid(aPhonebookUid) != KErrNone)
       
   540 		{
       
   541 		aSession.CompleteRequest(aMessage, KErrNotSupported);
       
   542 		return;
       
   543 		}
       
   544 	
       
   545 	//
       
   546 	// Check a sync request is not in progress or queued for this phonebook...
       
   547 	//
       
   548 	if (IsEngineRequestQueued(ESyncDoSynchronisation, aPhonebookUid, ETrue, ETrue))
       
   549 		{
       
   550 		aSession.CompleteRequest(aMessage, KErrInUse);
       
   551 		return;
       
   552 		}
       
   553 
       
   554 	//
       
   555 	// Queue the request to the engine...
       
   556 	//
       
   557 	QueueEngineRequestL(ESyncDoSynchronisation, aPhonebookUid, KNullContactId,
       
   558 						&aSession, aMessage);
       
   559 	} // CPhoneBookServer::DoSynchronisationL
       
   560 	
       
   561 	
       
   562 /**
       
   563  *  Requests the supported phonebook field formats for the specified phonebook.
       
   564  *
       
   565  *  @param aPhonebookUid   UID of the ICC phonebook to perform the operation on.
       
   566  *  @param aContactFields  The returned contact fields.
       
   567  *
       
   568  *  @return KErrNone if successful, a system-wide error code if not.
       
   569  */
       
   570 TInt CPhoneBookServer::GetContactFormatL(TUid aPhonebookUid,
       
   571 										 RPhoneBookSession::TContactFieldsV3& aContactFields)
       
   572 	{
       
   573 	LOGSERVER2(_L8("GetContactFormatL(0x%08x)"), aPhonebookUid);
       
   574 
       
   575 	//
       
   576 	// Is the server configured for use?
       
   577 	//
       
   578 	if (iServerConfigLevel != EServerConfigurationFull)
       
   579 		{
       
   580 		return(KErrNotReady);
       
   581 		}
       
   582 
       
   583 	//	
       
   584 	// Get the Contact Fields from the phonebook via the Phonebook Manager.
       
   585 	//
       
   586 	TInt result = iPhonebookManager->GetContactFields(aPhonebookUid,
       
   587 													  aContactFields);
       
   588 	
       
   589 	return(result);
       
   590 	} // CPhoneBookServer::GetContactFormatL
       
   591 
       
   592 
       
   593 /**
       
   594  *  Return the current setting for the Synchronisation Mode for the specified
       
   595  *  phonebook. The request will complete with KErrNone if the setting is
       
   596  *  successfully returned.
       
   597  * 
       
   598  *  @param aPhonebookUid  UID of the ICC phonebook to perform the operation on.
       
   599  *  @param aSyncMode      The returned sync mode.
       
   600  *
       
   601  *  @return KErrNone if successful, a system-wide error code if not.
       
   602  */
       
   603 TInt CPhoneBookServer::GetSyncModeL(TUid aPhonebookUid,
       
   604 									RPhoneBookSession::TPhonebookSyncMode& aSyncMode)
       
   605 	{
       
   606 	LOGSERVER2(_L8("GetSyncModeL(0x%08x)"), aPhonebookUid);
       
   607 
       
   608 	//
       
   609 	// Is the server configured for use?
       
   610 	//
       
   611 	if (iServerConfigLevel != EServerConfigurationFull)
       
   612 		{
       
   613 		return(KErrNotReady);
       
   614 		}
       
   615 
       
   616 	//	
       
   617 	// Get the Sync Mode from the Phonebook via the Phonebook Manager.
       
   618 	//
       
   619 	TInt  result = iPhonebookManager->GetSyncMode(aPhonebookUid, aSyncMode);
       
   620 	
       
   621 	return result;
       
   622 	} // CPhoneBookServer::GetSyncModeL
       
   623 
       
   624 
       
   625 /**
       
   626  *  Set the Synchronisation Mode for the specified phonebook.
       
   627  *
       
   628  *  If the mode is changing to EAutoCurrentIcc and no sync has yet been performed,
       
   629  *  then an automatic sync will be performed.
       
   630  * 
       
   631  *  @param aPhonebookUid  UID of the ICC phonebook to perform the operation on.
       
   632  *  @param aSyncMode      The new sync mode.
       
   633  *
       
   634  *  @return KErrNone if successful, a system-wide error code if not.
       
   635  */
       
   636 TInt CPhoneBookServer::SetSyncModeL(TUid aPhonebookUid,
       
   637 									RPhoneBookSession::TPhonebookSyncMode aSyncMode)
       
   638 	{
       
   639 	LOGSERVER2(_L8("SetSyncModeL(0x%08x)"), aPhonebookUid);
       
   640 
       
   641 	//
       
   642 	// Is the server configured for use?
       
   643 	//
       
   644 	if (iServerConfigLevel != EServerConfigurationFull)
       
   645 		{
       
   646 		return(KErrNotReady);
       
   647 		}
       
   648 
       
   649 	//
       
   650 	// If the new sync mode is EAutoCurrentIcc then get the current Sync
       
   651 	// Mode and Sync State. This will determine if an AutoSync should be
       
   652 	// queued following the change.
       
   653 	//
       
   654 	TBool  autoSyncNeeded(EFalse);
       
   655 	TInt  result(KErrUnknown);
       
   656 
       
   657 	if (aSyncMode == RPhoneBookSession::EAutoCurrentIcc)
       
   658 		{
       
   659 		//
       
   660 		// Get the current sync mode...
       
   661 		//
       
   662 		RPhoneBookSession::TPhonebookSyncMode  oldSyncMode;
       
   663 
       
   664 		result = iPhonebookManager->GetSyncMode(aPhonebookUid,
       
   665 												oldSyncMode);
       
   666 		if (result != KErrNone)
       
   667 			{
       
   668 			return result;
       
   669 			}
       
   670 		
       
   671 		//
       
   672 		// Get the current sync state...
       
   673 		//
       
   674 		RPhoneBookSession::TSyncState  syncState;
       
   675 
       
   676 		result = iPhonebookManager->GetSyncState(aPhonebookUid,
       
   677 												 syncState);
       
   678 		if (result != KErrNone)
       
   679 			{
       
   680 			return result;
       
   681 			}
       
   682 		
       
   683 		//
       
   684 		// Find out if the phonebook info has been retrieved...
       
   685 		//
       
   686 		TInt  phBkInfoRetrievedResult;
       
   687 		
       
   688 		result = iPhonebookManager->GetPhBkInfoRetrievedResult(aPhonebookUid,
       
   689 														       phBkInfoRetrievedResult);
       
   690 		if (result != KErrNone)
       
   691 			{
       
   692 			return result;
       
   693 			}
       
   694 		
       
   695 		//
       
   696 		// If the sync mode is changing, the phonebook was previously
       
   697 		// unsynchronised and the phonebook info is retrieved then
       
   698 		// an auto-sync will be needed.
       
   699 		//
       
   700 		if (oldSyncMode != RPhoneBookSession::EAutoCurrentIcc  &&
       
   701 			syncState == RPhoneBookSession::EUnsynchronised  &&
       
   702 			phBkInfoRetrievedResult != KErrNotReady)
       
   703 			{
       
   704 			autoSyncNeeded = ETrue;
       
   705 			}
       
   706 		}
       
   707 
       
   708 	//
       
   709 	// Set the Sync Mode in the Phonebook via the Phonebook Manager.
       
   710 	//
       
   711 	result = iPhonebookManager->SetSyncMode(aPhonebookUid, aSyncMode);
       
   712 
       
   713 	//
       
   714 	// Queue an auto sync if needed...
       
   715 	//
       
   716 	if (autoSyncNeeded)
       
   717 		{
       
   718 		QueueAutoSyncRequest(aPhonebookUid);
       
   719 		}
       
   720 
       
   721 	return result;
       
   722 	} // CPhoneBookServer::SetSyncModeL
       
   723 
       
   724 
       
   725 /**
       
   726  *  Delete an entry specified by aContactId from the ICC phonebook store
       
   727  *  it exists in.  This is an asynchronous request that will result in an
       
   728  *  engine request being posted to the engine.
       
   729  *
       
   730  *  If a DoSynchronisation or an existing DeleteCntFromICC request has already
       
   731  *  been posted for the same phonebook, KErrInUse will be returned.
       
   732  *
       
   733  *  @param aSession    A reference to the client session.
       
   734  *  @param aMessage    A reference to the client request.
       
   735  *  @param aContactId  ID of the contact to delete.
       
   736  */
       
   737 void CPhoneBookServer::DeleteCntFromICCL(CPhoneBookSession& aSession,
       
   738 										 const RMessage2& aMessage,
       
   739 										 TContactItemId aContactId)
       
   740 	{
       
   741 	LOGSERVER2(_L8("DeleteCntFromICCL(0%d)"), aContactId);
       
   742 
       
   743 	//
       
   744 	// Is the server configured for use?
       
   745 	//
       
   746 	if (iServerConfigLevel != EServerConfigurationFull)
       
   747 		{
       
   748 		aSession.CompleteRequest(aMessage, KErrNotReady);
       
   749 		return;
       
   750 		}
       
   751 
       
   752 	//
       
   753 	// Get the phonebook UID from the contact UID.
       
   754 	//
       
   755 	TUid phonebookUid = iPhonebookManager->GetPhonebookUidFromContactId(aContactId);
       
   756 
       
   757 	if (phonebookUid == KUidIccPhonebookNotSpecified)
       
   758 		{
       
   759 		aSession.CompleteRequest(aMessage, KErrArgument);
       
   760 		return;
       
   761 		}
       
   762 
       
   763 	//
       
   764 	// Check a sync or delete request is not in progress or queued for this
       
   765 	// phonebook...
       
   766 	//
       
   767 	if (IsEngineRequestQueued(ESyncDoSynchronisation, phonebookUid, ETrue, ETrue)  ||
       
   768 		IsEngineRequestQueued(ESyncDeleteCntFromICC, phonebookUid, ETrue, ETrue))
       
   769 		{
       
   770 		aSession.CompleteRequest(aMessage, KErrInUse);
       
   771 		return;
       
   772 		}
       
   773 
       
   774 	QueueEngineRequestL(ESyncDeleteCntFromICC, phonebookUid, aContactId,
       
   775 						&aSession, aMessage);
       
   776 	} // CPhoneBookServer::DeleteCntFromICCL
       
   777 
       
   778 
       
   779 /**
       
   780  *  Write an entry to a specified ICC phonebook store. This is an asynchronous
       
   781  *  request that will result in an engine request being posted to the engine.
       
   782  *
       
   783  *  If a DoSynchronisation or WriteCntToICCL request has already been posted
       
   784  *  for the same phonebook then KErrInUse will be returned.
       
   785  *
       
   786  *  @param aSession     A reference to the client session.
       
   787  *  @param aMessage     A reference to the client request.
       
   788  *  @param aSlotNum     The desired slot number or KSyncIndexNotSupplied.
       
   789  *  @param aTemplateId  ID of the contact template to base the entry on.
       
   790  */
       
   791 void CPhoneBookServer::WriteCntToICCL(CPhoneBookSession& aSession,
       
   792 									  const RMessage2& aMessage,
       
   793 									  TInt aSlotNum,
       
   794 									  TContactItemId aTemplateId)
       
   795 	{
       
   796 	LOGSERVER2(_L8("WriteCntToICCL(%d)"), aTemplateId);
       
   797 
       
   798 	//
       
   799 	// Is the server configured for use?
       
   800 	//
       
   801 	if (iServerConfigLevel != EServerConfigurationFull)
       
   802 		{
       
   803 		aSession.CompleteRequest(aMessage, KErrNotReady);
       
   804 		return;
       
   805 		}
       
   806 	
       
   807 	//
       
   808 	// Check a sync or write request is not in progress or queued for this
       
   809 	// phonebook...
       
   810 	//
       
   811 	TUid  phonebookUid = iPhonebookManager->GetPhonebookUidFromTemplateId(aTemplateId);
       
   812 
       
   813 	if (IsEngineRequestQueued(ESyncDoSynchronisation, phonebookUid, ETrue, ETrue)  ||
       
   814 		IsEngineRequestQueued(ESyncWriteCntToICC, phonebookUid, ETrue, ETrue))
       
   815 		{
       
   816 		aSession.CompleteRequest(aMessage, KErrInUse);
       
   817 		return;
       
   818 		}
       
   819 
       
   820 	//
       
   821 	// This request can only proceed if the cache is valid. Since no sync
       
   822 	// requests are pending or in progress, we can check this now.
       
   823 	//
       
   824 	RPhoneBookSession::TSyncState  syncState;
       
   825 	TInt  result;
       
   826 	
       
   827 	result = iPhonebookManager->GetSyncState(phonebookUid, syncState);
       
   828 	if (result != KErrNone)
       
   829 		{
       
   830 		aSession.CompleteRequest(aMessage, result);
       
   831 		return;
       
   832 		}
       
   833 	
       
   834 	if (syncState != RPhoneBookSession::ECacheValid)
       
   835 		{
       
   836 		aSession.CompleteRequest(aMessage, KErrNotReady);
       
   837 		return;
       
   838 		}
       
   839 
       
   840 	//
       
   841 	// If a slot number is supplied, check it is valid. Again we can do this
       
   842 	// now as it won't change...
       
   843 	//
       
   844 	if (aSlotNum != KSyncIndexNotSupplied)
       
   845 		{
       
   846 		RMobilePhoneBookStore::TMobilePhoneBookInfoV5  phBkInfo;
       
   847 		TInt  result;
       
   848 		
       
   849 		result = iPhonebookManager->GetPhoneBookInfo(phonebookUid, phBkInfo);
       
   850 		if (result != KErrNone)
       
   851 			{
       
   852 			aSession.CompleteRequest(aMessage, result);
       
   853 			return;
       
   854 			}
       
   855 
       
   856 		if (aSlotNum < 1  ||  aSlotNum > phBkInfo.iTotalEntries)
       
   857 			{
       
   858 			aSession.CompleteRequest(aMessage, KErrArgument);
       
   859 			return;
       
   860 			}
       
   861 		}
       
   862 
       
   863 	//
       
   864 	// Queue the request for the engine...
       
   865 	//
       
   866 	QueueEngineRequestL(ESyncWriteCntToICC, phonebookUid, KNullContactId,
       
   867 						&aSession, aMessage);
       
   868 	} // CPhoneBookServer::WriteCntToICCL
       
   869 
       
   870 
       
   871 /**
       
   872  *  Check whether an ICC entry is allowed to be read/write/edit on behalf of
       
   873  *  the client. The request will complete with KErrNone if the operation could
       
   874  *  be performed.
       
   875  * 
       
   876  *  @param aContactId   Contact Item ID
       
   877  *  @param aValidateOp  Type of operation that needs to be validated
       
   878  *
       
   879  *  @return KErrNone if validation was successful, otherwise returns an error.
       
   880  */
       
   881 TInt CPhoneBookServer::ValidateContactL(TContactItemId aContactId,
       
   882 									    MContactSynchroniser::TValidateOperation aValidateOp)
       
   883 	{
       
   884 	LOGSERVER2(_L8("ValidateContactL(%d)"), aContactId);
       
   885 
       
   886 	//
       
   887 	// Is the server configured for use?
       
   888 	//
       
   889 	if (iServerConfigLevel != EServerConfigurationFull)
       
   890 		{
       
   891 		return KErrNotReady;
       
   892 		}
       
   893 
       
   894 	//
       
   895 	// Get the contact UID from the phonebook...
       
   896 	//
       
   897 	TUid  phonebookUid = iPhonebookManager->GetPhonebookUidFromContactId(aContactId);
       
   898 
       
   899 	if (phonebookUid == KUidIccPhonebookNotSpecified)
       
   900 		{
       
   901 		return KErrNotFound;
       
   902 		}
       
   903 
       
   904 	//
       
   905 	// This request can only proceed if the cache is valid...
       
   906 	//
       
   907 	RPhoneBookSession::TSyncState  syncState;
       
   908 	TInt  result;
       
   909 	
       
   910 	result = iPhonebookManager->GetSyncState(phonebookUid, syncState);
       
   911 	if (result != KErrNone)
       
   912 		{
       
   913 		return result;
       
   914 		}
       
   915 	
       
   916 	if (syncState != RPhoneBookSession::ECacheValid)
       
   917 		{
       
   918 		return KErrNotReady;
       
   919 		}
       
   920 
       
   921 	//
       
   922 	// First check whether phonebook can be accessed, i.e. whether ICC is
       
   923 	// pin-locked/blocked...
       
   924 	//
       
   925 	if (iPhonebookManager->IsPin1Valid() == EFalse  ||
       
   926 		(phonebookUid == KUidUsimAppAdnPhonebook  &&
       
   927 		 iPhonebookManager->IsUsimAppPinValid() == EFalse))
       
   928 		{
       
   929 		return KErrAccessDenied;
       
   930 		}
       
   931 
       
   932 	//
       
   933 	// Check the available types of access...
       
   934 	//
       
   935 	RMobilePhoneBookStore::TMobilePhoneBookInfoV5  phBkInfo;
       
   936 	
       
   937 	result = iPhonebookManager->GetPhoneBookInfo(phonebookUid, phBkInfo);
       
   938 	if (result != KErrNone)
       
   939 		{
       
   940 		return result;
       
   941 		}
       
   942 
       
   943 	switch (aValidateOp)
       
   944 		{
       
   945 		case MContactSynchroniser::ERead:
       
   946 		case MContactSynchroniser::ESearch:
       
   947 			{
       
   948 			if (phBkInfo.iCaps & RMobilePhoneStore::KCapsReadAccess == 0)
       
   949 				{
       
   950 				return KErrAccessDenied;
       
   951 				}
       
   952 			}
       
   953 			break;
       
   954 
       
   955 		case MContactSynchroniser::EEdit:
       
   956 			{
       
   957 			if (phBkInfo.iCaps & RMobilePhoneStore::KCapsWriteAccess == 0)
       
   958 				{
       
   959 				return KErrAccessDenied;
       
   960 				}
       
   961 			
       
   962 			 //
       
   963 			 // For FDN Phonebook, can only edit if PIN2 is set
       
   964 			 //
       
   965 			 if (phonebookUid == KUidIccGlobalFdnPhonebook  &&
       
   966 			 	 iPhonebookManager->IsPin2Valid() == EFalse)
       
   967 				{
       
   968 				return KErrAccessDenied;
       
   969 				}
       
   970 			}	
       
   971 			break;
       
   972 
       
   973 		default:
       
   974 			{
       
   975 			return(KErrNotSupported);
       
   976 			}
       
   977 		}
       
   978 
       
   979 	//
       
   980 	// Finally, check whether the entry exists in the Look-Up Table...
       
   981 	//
       
   982 	return iPhonebookManager->IsEntryInTable(phonebookUid, aContactId);
       
   983 	} // CPhoneBookServer::ValidateContactL
       
   984 
       
   985 
       
   986 /**
       
   987  *  Update an entry in the Phonebook Sync's look-up table for the specified
       
   988  *  phonebook by adding the Contacts ID supplied by the client (Contacts Model)
       
   989  *  into the specified slot number.
       
   990  *
       
   991  *  @param aPhonebookUid  UID of the ICC phonebook to perform the operation on.
       
   992  *  @param aContactId     Contact Item ID
       
   993  *  @param aSlotNum       The slot number of the entry.
       
   994  *
       
   995  *  @return KErrNone if the table was updated successfully, otherwise returns an error.
       
   996  */
       
   997 TInt CPhoneBookServer::UpdateLookupTableL(TUid aPhonebookUid,
       
   998 										  TContactItemId aContactId,
       
   999 									      TInt aSlotNum)
       
  1000 	{
       
  1001 	LOGSERVER2(_L8("UpdateLookupTableL(0x%08x)"), aPhonebookUid);
       
  1002 
       
  1003 	//
       
  1004 	// Is the server configured for use?
       
  1005 	//
       
  1006 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1007 		{
       
  1008 		return KErrNotReady;
       
  1009 		}
       
  1010 
       
  1011 	//
       
  1012 	// This request can only proceed if the cache is valid...
       
  1013 	//
       
  1014 	RPhoneBookSession::TSyncState  syncState;
       
  1015 	TInt  result;
       
  1016 	
       
  1017 	result = iPhonebookManager->GetSyncState(aPhonebookUid, syncState);
       
  1018 	if (result != KErrNone)
       
  1019 		{
       
  1020 		return result;
       
  1021 		}
       
  1022 
       
  1023 	if (syncState != RPhoneBookSession::ECacheValid)
       
  1024 		{
       
  1025 		return KErrNotReady;
       
  1026 		}
       
  1027 
       
  1028 	//
       
  1029 	// Update the entry in the loop-up-table...
       
  1030 	//
       
  1031 	result = iPhonebookManager->UpdateEntryInTable(aPhonebookUid,
       
  1032 												   aSlotNum, aContactId);
       
  1033 
       
  1034 	return result;
       
  1035 	} // CPhoneBookServer::UpdateLookupTableL
       
  1036 
       
  1037 
       
  1038 /**
       
  1039  *  Return the ICC entry template or group ID for a specified phonebook.
       
  1040  *
       
  1041  *  @param aPhonebookUid   UID of the ICC phonebook to perform the operation on.
       
  1042  *  @param aSyncIdType     Either ESyncTemplateId or ESyncGroupId.
       
  1043  *  @param aContactItemId  Returned contact ID.
       
  1044  *
       
  1045  *  @return KErrNone if the ID was returned successfully, otherwise returns an error.
       
  1046  */
       
  1047 TInt CPhoneBookServer::GetPhoneBookIdL(TUid aPhonebookUid,
       
  1048 								       RPhoneBookSession::TSyncIdType aSyncIdType,
       
  1049 									   TContactItemId& aContactItemId)
       
  1050 	{
       
  1051 	LOGSERVER2(_L8("GetPhoneBookIdL(0x%08x)"), aPhonebookUid);
       
  1052 
       
  1053 	//
       
  1054 	// Is the server configured for use?
       
  1055 	//
       
  1056 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1057 		{
       
  1058 		return KErrNotReady;
       
  1059 		}
       
  1060 	
       
  1061 	//
       
  1062 	// Get the required contact ID...
       
  1063 	//
       
  1064 	TInt  result(KErrArgument);
       
  1065 	
       
  1066 	if (aSyncIdType == RPhoneBookSession::ESyncTemplateId)
       
  1067 		{
       
  1068 		result = iPhonebookManager->GetTemplateId(aPhonebookUid,
       
  1069 												  aContactItemId);
       
  1070 		}
       
  1071 	else if (aSyncIdType == RPhoneBookSession::ESyncGroupId)
       
  1072 		{
       
  1073 		result = iPhonebookManager->GetGroupId(aPhonebookUid,
       
  1074 											   aContactItemId);
       
  1075 		}
       
  1076 
       
  1077 	return(result);
       
  1078 	} // CPhoneBookServer::GetPhoneBookIdL
       
  1079 
       
  1080 
       
  1081 /**
       
  1082  *  Return the current phonebook server cache state.
       
  1083  * 
       
  1084  *  @param aPhonebookUid   UID of the ICC phonebook to perform the operation on.
       
  1085  *  @param aContactItemId  Returned cache state.
       
  1086  *
       
  1087  *  @return KErrNone if the cache state was returned successfully, otherwise returns
       
  1088  *          an error.
       
  1089  */
       
  1090 TInt CPhoneBookServer::GetCacheStateL(TUid aPhonebookUid,
       
  1091 								      RPhoneBookSession::TSyncState& aSyncState)
       
  1092 	{
       
  1093 	LOGSERVER2(_L8("GetCacheStateL(0x%08x)"), aPhonebookUid);
       
  1094 
       
  1095 	//
       
  1096 	// Is the server configured for use?
       
  1097 	//
       
  1098 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1099 		{
       
  1100 		return KErrNotReady;
       
  1101 		}
       
  1102 
       
  1103 	//
       
  1104 	// Check if the phonebook is supported...
       
  1105 	//
       
  1106 	TInt  result, phBkInfoRetrievedResult;
       
  1107 	
       
  1108 	result = iPhonebookManager->GetPhBkInfoRetrievedResult(aPhonebookUid,
       
  1109 														   phBkInfoRetrievedResult);
       
  1110 	if (result != KErrNone)
       
  1111 		{
       
  1112 		return result;
       
  1113 		}
       
  1114 	
       
  1115 	if (phBkInfoRetrievedResult != KErrNone)
       
  1116 		{
       
  1117 		return phBkInfoRetrievedResult;
       
  1118 		}
       
  1119 
       
  1120 	return iPhonebookManager->GetSyncState(aPhonebookUid, aSyncState);
       
  1121 	} // CPhoneBookServer::GetCacheStateL
       
  1122 
       
  1123 
       
  1124 /**
       
  1125  *  Marks the start of checking the server's and engine's heap. 
       
  1126  *  This function only works in debug releases.
       
  1127  *
       
  1128  *  Calls to this function can be nested but each call must be matched by
       
  1129  *  corresponding DbgMarkEnd().
       
  1130  *
       
  1131  *  @return  KErrNone.
       
  1132  */
       
  1133 TInt CPhoneBookServer::DbgMarkHeap() const
       
  1134 	{
       
  1135 #ifdef _DEBUG
       
  1136 	__UHEAP_MARK;
       
  1137 #endif
       
  1138 
       
  1139 	return(KErrNone);
       
  1140 	} // CPhoneBookServer::DbgMarkHeap
       
  1141 
       
  1142 
       
  1143 /**
       
  1144  *  Checks that the number of allocated cells at the current nested level on
       
  1145  *  the server's and engine's heaps are the same as the specified value.
       
  1146  *  This function only works for debug builds.
       
  1147  *
       
  1148  *  @param aCount  The number of heap cells expected to be allocated at
       
  1149  *                 the current nest level.
       
  1150  *
       
  1151  *  @return  KErrNone.
       
  1152  */
       
  1153 TInt CPhoneBookServer::DbgCheckHeap(TInt aCount) const
       
  1154 	{
       
  1155 #ifdef _DEBUG 
       
  1156 	__UHEAP_CHECK(aCount);
       
  1157 #else
       
  1158 	(void) aCount;
       
  1159 #endif
       
  1160 
       
  1161 	return(KErrNone);
       
  1162 	} // CPhoneBookServer::DbgCheckHeap
       
  1163 
       
  1164 
       
  1165 /**
       
  1166  *  Marks the end of checking the current server's and engine's heap. 
       
  1167  *
       
  1168  *  The function expects aCount heap cells to remain allocated at the
       
  1169  *  current nest level. This function must match an earlier call to
       
  1170  *  DbgMarkHeap() and only functions on debug releases.
       
  1171  *
       
  1172  *  @param aCount  The number of heap cells expected to remain allocated
       
  1173  *                 at the current nest level.
       
  1174  *
       
  1175  *  @return  KErrNone.
       
  1176  */
       
  1177 TInt CPhoneBookServer::DbgMarkEnd(TInt aCount) const
       
  1178 	{
       
  1179 #ifdef _DEBUG
       
  1180 	__UHEAP_MARKENDC(aCount);
       
  1181 #else
       
  1182 	(void) aCount;
       
  1183 #endif
       
  1184 
       
  1185 	return(KErrNone);
       
  1186 	} // CPhoneBookServer::DbgMarkEnd
       
  1187 
       
  1188 
       
  1189 /**
       
  1190  *  Simulates heap allocation failure for the sever and engine.
       
  1191  *
       
  1192  *  The failure occurs on the next call to new or any of the functions which 
       
  1193  *  allocate memory from the heap. This is defined only for debug builds.
       
  1194  *
       
  1195  *  @param aCount  Determines when the allocation will fail.
       
  1196  *
       
  1197  *  @return  KErrNone.
       
  1198  */
       
  1199 TInt CPhoneBookServer::DbgFailNext(TInt aCount) const
       
  1200 	{
       
  1201 #ifdef _DEBUG
       
  1202 	if (aCount == 0)
       
  1203 		{
       
  1204 		__UHEAP_RESET;
       
  1205 		}
       
  1206 	else
       
  1207 		{
       
  1208 		__UHEAP_FAILNEXT(aCount);
       
  1209 		}
       
  1210 #else
       
  1211 	(void) aCount;
       
  1212 #endif
       
  1213 
       
  1214 	return(KErrNone);
       
  1215 	} // CPhoneBookServer::DbgFailNext
       
  1216 
       
  1217 
       
  1218 /**
       
  1219  *  Cancel a previous synchronisation request.
       
  1220  *
       
  1221  *  @param aSession       Reference to the client's session.
       
  1222  *  @param aPhonebookUid  UID of the ICC phonebook to cancel the sync request.
       
  1223  *
       
  1224  *  @return KErrNone if the request was cancelled, otherwise returns an error.
       
  1225  */
       
  1226 TInt CPhoneBookServer::DoSynchronisationCancelL(CPhoneBookSession& aSession,
       
  1227 												TUid aPhonebookUid)
       
  1228 	{
       
  1229 	LOGSERVER2(_L8("DoSynchronisationCancelL(): 0x%08x"), aPhonebookUid);
       
  1230 
       
  1231 	CancelEngineRequest(ESyncDoSynchronisation, aPhonebookUid,
       
  1232 						KNullContactId, &aSession);
       
  1233 
       
  1234 	return(KErrNone);
       
  1235 	} // CPhoneBookServer::DoSynchronisationCancelL
       
  1236 
       
  1237 
       
  1238 /**
       
  1239  *  Cancel a previous delete contact request.
       
  1240  *
       
  1241  *  @param aSession       Reference to the client's session.
       
  1242  *  @param aPhonebookUid  UID of the ICC phonebook to cancel the delete request.
       
  1243  *
       
  1244  *  @return KErrNone if the request was cancelled, otherwise returns an error.
       
  1245  */
       
  1246 TInt CPhoneBookServer::DeleteCntFromICCCancelL(CPhoneBookSession& aSession,
       
  1247 												TUid aPhonebookUid)
       
  1248 	{
       
  1249 	LOGSERVER2(_L8("DeleteCntFromICCCancelL(0x%08x)"), aPhonebookUid);
       
  1250 
       
  1251 	CancelEngineRequest(ESyncDeleteCntFromICC, aPhonebookUid,
       
  1252 						KNullContactId, &aSession);
       
  1253 
       
  1254 	return(KErrNone);
       
  1255 	} // CPhoneBookServer::DeleteCntFromICCCancelL
       
  1256 
       
  1257 
       
  1258 /**
       
  1259  *  Cancel a previous write contact request.
       
  1260  *
       
  1261  *  @param aSession       Reference to the client's session.
       
  1262  *  @param aPhonebookUid  UID of the ICC phonebook to cancel the write request.
       
  1263  *
       
  1264  *  @return KErrNone if the request was cancelled, otherwise returns an error.
       
  1265  */
       
  1266 TInt CPhoneBookServer::WriteCntToICCCancelL(CPhoneBookSession& aSession,
       
  1267 											TUid aPhonebookUid)
       
  1268 	{
       
  1269 	LOGSERVER2(_L8("WriteCntToICCCancelL(0x%08x)"), aPhonebookUid);
       
  1270 
       
  1271 	CancelEngineRequest(ESyncDoSynchronisation, aPhonebookUid,
       
  1272 						KNullContactId, &aSession);
       
  1273 
       
  1274 	return(KErrNone);
       
  1275 	} // CPhoneBookServer::WriteCntToICCCancelL
       
  1276 
       
  1277 
       
  1278 /**
       
  1279  *  Stores the current message for later completion when the cache state of the
       
  1280  *  specified phonebook changes.
       
  1281  *
       
  1282  *  @param aSession       Reference to the client's session.
       
  1283  *  @param aMessage       Reference to the client's request.
       
  1284  *  @param aPhonebookUid  UID of the ICC phonebook to monitor.
       
  1285  */
       
  1286 void CPhoneBookServer::NotifyCacheStateChangeL(CPhoneBookSession& aSession,
       
  1287 											   const RMessage2& aMessage,
       
  1288 											   TUid aPhonebookUid)
       
  1289 	{
       
  1290 	LOGSERVER2(_L8("NotifyCacheStateChangeL(0x%08x)"), aPhonebookUid);
       
  1291 
       
  1292 	//
       
  1293 	// Is the server configured for use?
       
  1294 	//
       
  1295 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1296 		{
       
  1297 		aSession.CompleteRequest(aMessage, KErrNotReady);
       
  1298 		return;
       
  1299 		}
       
  1300 
       
  1301 	//	
       
  1302 	// Validate the phonebook UID to ensure notifications can only be posted
       
  1303 	// for valid phonebooks.
       
  1304 	//
       
  1305 	TInt  result;
       
  1306 
       
  1307 	result = iPhonebookManager->ValidatePhonebookUid(aPhonebookUid);
       
  1308 	if (result != KErrNone)
       
  1309 		{
       
  1310 		aSession.CompleteRequest(aMessage, result);
       
  1311 		return;
       
  1312 		}
       
  1313 
       
  1314 	//
       
  1315 	// Create Notification Request Object and add to the array...
       
  1316 	//
       
  1317 	TCacheStateNotification  notifyRequest;
       
  1318 
       
  1319 	notifyRequest.iSession      = &aSession;
       
  1320 	notifyRequest.iMessage      = aMessage;
       
  1321 	notifyRequest.iPhonebookUid = aPhonebookUid;
       
  1322 
       
  1323 	result = iCacheStateNotificationArray.Append(notifyRequest);
       
  1324 	if (result != KErrNone)
       
  1325 		{
       
  1326 		aSession.CompleteRequest(aMessage, result);
       
  1327 		return;
       
  1328 		}
       
  1329 	} // CPhoneBookServer::NotifyCacheStateChangeL
       
  1330 
       
  1331 
       
  1332 /**
       
  1333  *  Cancel a previous notify state change request.
       
  1334  *
       
  1335  *  @param aSession       Reference to the client's session.
       
  1336  *  @param aPhonebookUid  UID of the ICC phonebook to cancel the notify request.
       
  1337  *
       
  1338  *  @return KErrNone if the request was cancelled, otherwise returns an error.
       
  1339  */
       
  1340 TInt CPhoneBookServer::NotifyCacheStateChangeCancelL(CPhoneBookSession& aSession,
       
  1341 													 TUid aPhonebookUid)
       
  1342 	{
       
  1343 	LOGSERVER2(_L8("NotifyCacheStateChangeCancelL(0x%08x)"), aPhonebookUid);
       
  1344 
       
  1345 	//
       
  1346 	// Is the server configured for use?
       
  1347 	//
       
  1348 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1349 		{
       
  1350 		return KErrNotReady;
       
  1351 		}
       
  1352 	
       
  1353 	//
       
  1354 	// Cancel the notification by completing the request with KErrCancel...
       
  1355 	//
       
  1356 	for (TInt index = 0;  index < iCacheStateNotificationArray.Count();  index++)
       
  1357 		{
       
  1358 		TCacheStateNotification  notifyRequest = iCacheStateNotificationArray[index];
       
  1359 
       
  1360 		if (notifyRequest.iSession == &aSession  &&
       
  1361 			notifyRequest.iPhonebookUid == aPhonebookUid)
       
  1362 			{
       
  1363 			//
       
  1364 			// If it is in the list then cancel it, and remove it...
       
  1365 			//
       
  1366 			aSession.CompleteRequest(notifyRequest.iMessage, KErrCancel);
       
  1367 
       
  1368 			iCacheStateNotificationArray.Remove(index);
       
  1369 			index--;
       
  1370 			}
       
  1371 		}
       
  1372 
       
  1373 	return(KErrNone);
       
  1374 	} // CPhoneBookServer::NotifyCacheStateChangeCancelL
       
  1375 
       
  1376 
       
  1377 /**
       
  1378  *  Returns the last error found during synchronisation on the specified phonebook.
       
  1379  *
       
  1380  *  @param aPhonebookUid   UID of the ICC phonebook to examine.
       
  1381  *  @param aLastSyncError  Returned value of the last error.
       
  1382  *
       
  1383  *  @return KErrNone if the last error was returned, otherwise returns an error.
       
  1384  */
       
  1385 TInt CPhoneBookServer::GetLastSyncErrorL(TUid aPhonebookUid,
       
  1386 										 TInt& aLastSyncError)
       
  1387 	{
       
  1388 	LOGSERVER2(_L8("GetLastSyncErrorL(0x%08x)"), aPhonebookUid);
       
  1389 
       
  1390 	//
       
  1391 	// Is the server configured for use?
       
  1392 	//
       
  1393 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1394 		{
       
  1395 		return KErrNotReady;
       
  1396 		}
       
  1397 
       
  1398 	//
       
  1399 	// This request can only proceed if a sync request has been actioned...
       
  1400 	//
       
  1401 	RPhoneBookSession::TSyncState  syncState;
       
  1402 	TInt  result;
       
  1403 	
       
  1404 	result = iPhonebookManager->GetSyncState(aPhonebookUid, syncState);
       
  1405 	if (result != KErrNone)
       
  1406 		{
       
  1407 		return result;
       
  1408 		}
       
  1409 	
       
  1410 	if (syncState == RPhoneBookSession::EUnsynchronised)
       
  1411 		{
       
  1412 		return KErrNotReady;
       
  1413 		}
       
  1414 
       
  1415 	//
       
  1416 	// Get the last sync error form the phonebook parameters.
       
  1417 	//
       
  1418 	iPhonebookManager->GetLastSyncError(aPhonebookUid, aLastSyncError);
       
  1419 
       
  1420 	return KErrNone;
       
  1421 	} // CPhoneBookServer::GetLastSyncErrorL
       
  1422 
       
  1423 
       
  1424 /**
       
  1425  *  Returns the total number of slots for a specified phonebook.
       
  1426  *
       
  1427  *  @param aPhonebookUid  UID of the ICC phonebook to examine.
       
  1428  *  @param aNumSlots      Returned value of the number of slots.
       
  1429  *
       
  1430  *  @return KErrNone if the value was returned, otherwise returns an error.
       
  1431  */
       
  1432 TInt CPhoneBookServer::GetNumSlotsL(TUid aPhonebookUid, TInt& aNumSlots)
       
  1433 	{
       
  1434 	LOGSERVER2(_L8("GetNumSlotsL(0x%08x)"), aPhonebookUid);
       
  1435 
       
  1436 	//
       
  1437 	// Is the server configured for use?
       
  1438 	//
       
  1439 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1440 		{
       
  1441 		return KErrNotReady;
       
  1442 		}
       
  1443 
       
  1444 	//
       
  1445 	// Make sure we do not complete with the default value...
       
  1446 	//
       
  1447 	TInt  phBkInfoRetrievedResult;
       
  1448 	TInt  result;
       
  1449 
       
  1450 	result = iPhonebookManager->GetPhBkInfoRetrievedResult(aPhonebookUid,
       
  1451 														   phBkInfoRetrievedResult);
       
  1452 	if (result != KErrNone)
       
  1453 		{
       
  1454 		return result;
       
  1455 		}
       
  1456 
       
  1457 	if (phBkInfoRetrievedResult != KErrNone)
       
  1458 		{
       
  1459 		return phBkInfoRetrievedResult;
       
  1460 		}
       
  1461 
       
  1462 	//
       
  1463 	// This information can be obtained from the Phonebook Info data
       
  1464 	// (TMobilePhoneBookInfoV5) or the RMobilePhoneStore data (which populates)
       
  1465 	// the Look-Up Table size. Since the first option is not always supported,
       
  1466 	// it's easiest (and quickest) to return the Loop-Up Table size...
       
  1467 	//
       
  1468 	result = iPhonebookManager->GetLookUpTableSize(aPhonebookUid, aNumSlots);
       
  1469 	
       
  1470 	return result;
       
  1471 	} // CPhoneBookServer::GetNumSlotsL
       
  1472 
       
  1473 
       
  1474 /**
       
  1475  *  Return number of free slots for a specified phonebook.
       
  1476  *
       
  1477  *  @param aPhonebookUid  UID of the ICC phonebook to examine.
       
  1478  *  @param aNumFreeSlots  Returned value of the number of free slots.
       
  1479  *
       
  1480  *  @return KErrNone if the value was returned, otherwise returns an error.
       
  1481  */
       
  1482 TInt CPhoneBookServer::GetNumFreeSlotsL(TUid aPhonebookUid,
       
  1483 										TInt& aNumFreeSlots)
       
  1484 	{
       
  1485 	LOGSERVER2(_L8("GetNumFreeSlotsL(0x%08x)"), aPhonebookUid);
       
  1486 
       
  1487 	//
       
  1488 	// Is the server configured for use?
       
  1489 	//
       
  1490 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1491 		{
       
  1492 		return KErrNotReady;
       
  1493 		}
       
  1494 
       
  1495 	//
       
  1496 	// Get the current sync state for this phonebook...
       
  1497 	//
       
  1498 	RPhoneBookSession::TSyncState  syncState;
       
  1499 	TInt  result;
       
  1500 	
       
  1501 	result = iPhonebookManager->GetSyncState(aPhonebookUid, syncState);
       
  1502 	if (result != KErrNone)
       
  1503 		{
       
  1504 		return result;
       
  1505 		}
       
  1506 
       
  1507 	//
       
  1508 	// If the phone book is synchronised then take the value from the LUT.
       
  1509 	// Otherwise, take the value from the phone info structure. However, 
       
  1510 	// the phone may not support returning this information.
       
  1511 	//
       
  1512 	if (syncState == RPhoneBookSession::ECacheValid)
       
  1513 		{
       
  1514 		result = iPhonebookManager->GetNumFreeSlots(aPhonebookUid, aNumFreeSlots);
       
  1515 		if (result != KErrNone)
       
  1516 			{
       
  1517 			return result;
       
  1518 			}
       
  1519 		}
       
  1520 	else
       
  1521 		{
       
  1522 		RMobilePhoneBookStore::TMobilePhoneBookInfoV5  phBkInfo;
       
  1523 		
       
  1524 		result = iPhonebookManager->GetPhoneBookInfo(aPhonebookUid, phBkInfo);
       
  1525 	
       
  1526 		if (phBkInfo.iTotalEntries < 0  ||  phBkInfo.iUsedEntries < 0)
       
  1527 			{
       
  1528 			//
       
  1529 			// The TSY does not support this information.
       
  1530 			//
       
  1531 			return KErrUnknown;
       
  1532 			}
       
  1533 			
       
  1534 		aNumFreeSlots = phBkInfo.iTotalEntries - phBkInfo.iUsedEntries;
       
  1535 		}
       
  1536 	
       
  1537 	return KErrNone;
       
  1538 	} // CPhoneBookServer::GetNumFreeSlotsL
       
  1539 
       
  1540 
       
  1541 /**
       
  1542  *  Return an array of free slot numbers for a specified phonebook.
       
  1543  *
       
  1544  *  @param aPhonebookUid  UID of the ICC phonebook to examine.
       
  1545  *  @param aFreeSlots     Returned list of free slots.
       
  1546  *
       
  1547  *  @return KErrNone if the list was returned, otherwise returns an error.
       
  1548  */
       
  1549 TInt CPhoneBookServer::GetFreeSlotsL(TUid aPhonebookUid,
       
  1550 									 RArray<TInt>& aFreeSlots)
       
  1551 	{
       
  1552 	LOGSERVER2(_L8("GetFreeSlotsL(0x%08x)"), aPhonebookUid);
       
  1553 
       
  1554 	//
       
  1555 	// Is the server configured for use?
       
  1556 	//
       
  1557 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1558 		{
       
  1559 		return KErrNotReady;
       
  1560 		}
       
  1561 
       
  1562 	//
       
  1563 	// This request can only proceed if the cache is valid...
       
  1564 	//
       
  1565 	RPhoneBookSession::TSyncState  syncState;
       
  1566 	TInt  result;
       
  1567 	
       
  1568 	result = iPhonebookManager->GetSyncState(aPhonebookUid, syncState);
       
  1569 	if (result != KErrNone)
       
  1570 		{
       
  1571 		return result;
       
  1572 		}
       
  1573 
       
  1574 	if (syncState != RPhoneBookSession::ECacheValid)
       
  1575 		{
       
  1576 		return KErrNotReady;
       
  1577 		}
       
  1578 
       
  1579 	//
       
  1580 	// Return the list of free slots...
       
  1581 	//
       
  1582 	result = iPhonebookManager->GetMatchingEntries(aPhonebookUid, ESlotEmpty,
       
  1583 												   aFreeSlots);
       
  1584 	
       
  1585 	return result;
       
  1586 	} // CPhoneBookServer::GetFreeSlotsL
       
  1587 	
       
  1588 
       
  1589 /**
       
  1590  *  Return the contact ID assigned to an entry at a given slot in a specified
       
  1591  *  phonebook.
       
  1592  *
       
  1593  *  @param aPhonebookUid   UID of the ICC phonebook to examine.
       
  1594  *  @param aSlotNum        Slot number to examine.
       
  1595  *  @param aContactItemId  Returned contact ID.
       
  1596  *
       
  1597  *  @return KErrNone if the contact ID was returned, otherwise returns an error.
       
  1598  */
       
  1599 TInt CPhoneBookServer::GetSlotIdL(TUid aPhonebookUid, TInt aSlotNum,
       
  1600 								  TContactItemId& aContactItemId)
       
  1601 	{
       
  1602 	LOGSERVER2(_L8("GetSlotIdL(0x%08x)"), aPhonebookUid);
       
  1603 
       
  1604 	//
       
  1605 	// Is the server configured for use?
       
  1606 	//
       
  1607 	if (iServerConfigLevel != EServerConfigurationFull)
       
  1608 		{
       
  1609 		return KErrNotReady;
       
  1610 		}
       
  1611 
       
  1612 	//
       
  1613 	// This request can only proceed if the cache is valid...
       
  1614 	//
       
  1615 	RPhoneBookSession::TSyncState  syncState;
       
  1616 	TInt  result;
       
  1617 	
       
  1618 	result = iPhonebookManager->GetSyncState(aPhonebookUid, syncState);
       
  1619 	if (result != KErrNone)
       
  1620 		{
       
  1621 		return result;
       
  1622 		}
       
  1623 
       
  1624 	if (syncState != RPhoneBookSession::ECacheValid)
       
  1625 		{
       
  1626 		return KErrNotReady;
       
  1627 		}
       
  1628 
       
  1629 	//
       
  1630 	// Get the ID from the phonebook's Look Up Table...
       
  1631 	//
       
  1632 	result = iPhonebookManager->GetContactIdFromSlotNum(aPhonebookUid,
       
  1633 														aSlotNum,
       
  1634 														aContactItemId);
       
  1635 	
       
  1636 	return result;
       
  1637 	} // CPhoneBookServer::GetSlotIdL
       
  1638 
       
  1639 
       
  1640 /**
       
  1641  *  Requests the server to shut down when it no longer has any connected
       
  1642  *  sessions. This procedure is only premitted in debug builds and is provided
       
  1643  *  for testing purposes.
       
  1644  *
       
  1645  *  The server will shutdown when the last session disconnects.
       
  1646  *
       
  1647  *  @param aUnconditionally  If True it allows future connects to the server up
       
  1648  *                           until the last session disconnects.
       
  1649  *
       
  1650  *  @return KErrNone if the shutdown request was accepted, otherwise returns
       
  1651  *          an error.
       
  1652  */
       
  1653 TInt CPhoneBookServer::ShutdownServer(TBool aUnconditionally)
       
  1654 	{
       
  1655 	LOGSERVER1(_L8("ShutdownServer()"));
       
  1656 
       
  1657 	iShouldShutdownServer          = ETrue;
       
  1658 	iShouldShutdownUnconditionally = aUnconditionally;
       
  1659 
       
  1660 	//
       
  1661 	// Unconfigure the server now. Otherwise the engine may be holding a
       
  1662 	// handle on the Contacts DB, which could be holding a handle on the
       
  1663 	// PhBkSync plugin, which could be holding the last session on PhBkSync
       
  1664 	// and prevent the server from unconfiguring the engine, etc.
       
  1665 	//
       
  1666 	TRAP_IGNORE(ConfigureServerL(EServerConfigurationNone));
       
  1667 	
       
  1668 	return(KErrNone);
       
  1669 	} // CPhoneBookServer::ShutdownServer
       
  1670 
       
  1671 
       
  1672 /**
       
  1673  *  If a notification request is outstanding for the specified phonebook it is
       
  1674  *  completed.
       
  1675  *
       
  1676  *  @param aPhonebookUid  The phonebook for which the sync state has changed.
       
  1677  */
       
  1678 void CPhoneBookServer::CompleteNotifyStateChange(TUid aPhonebookUid)
       
  1679 	{
       
  1680 	LOGSERVER2(_L8("CompleteNotifyStateChange(): 0x%08x"), aPhonebookUid);
       
  1681 
       
  1682 	for (TInt index = 0;  index < iCacheStateNotificationArray.Count();  index++)
       
  1683 		{
       
  1684 		TCacheStateNotification  notifyRequest = iCacheStateNotificationArray[index];
       
  1685 
       
  1686 		if (notifyRequest.iPhonebookUid == aPhonebookUid)
       
  1687 			{
       
  1688 			//
       
  1689 			// If it is in the list then  complete the message and then remove
       
  1690 			// from the list.
       
  1691 			//
       
  1692 			notifyRequest.iSession->CompleteRequest(notifyRequest.iMessage,
       
  1693 												    KErrNone);
       
  1694 
       
  1695 			iCacheStateNotificationArray.Remove(index);
       
  1696 			index--;
       
  1697 			}
       
  1698 		}
       
  1699 	} // CPhoneBookServer::CompleteNotifyStateChange
       
  1700 
       
  1701 
       
  1702 /**
       
  1703  *  Connect to the ETel Sever, obtains the name of the currently selected TSY and
       
  1704  *  then loads the TSY.
       
  1705  */
       
  1706 void CPhoneBookServer::ConnectToEtelL()
       
  1707 	{
       
  1708 	LOGSERVER1(_L8("Connect to ETel")); 
       
  1709 	// Obtain the name of the currently selected TSY 	
       
  1710 	
       
  1711 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
  1712 	CMDBSession* db = CMDBSession::NewLC(KCDVersion1_2);
       
  1713 #else
       
  1714 	CMDBSession* db = CMDBSession::NewLC(KCDVersion1_1);
       
  1715 #endif
       
  1716 	
       
  1717 	CMDBField<TUint32>* globalSettingField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
       
  1718 	CleanupStack::PushL(globalSettingField);
       
  1719 
       
  1720 	globalSettingField->SetRecordId(1);
       
  1721 	globalSettingField->LoadL(*db);
       
  1722 	TUint32 modemId = *globalSettingField;
       
  1723 
       
  1724 	CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
       
  1725 	CleanupStack::PushL(tsyField);
       
  1726 
       
  1727 	tsyField->SetRecordId(modemId);
       
  1728 	TRAPD(err, tsyField->LoadL(*db));
       
  1729 	if (err != KErrNone)
       
  1730 		{
       
  1731 		LOGSERVER1(_L8("Unable to get default TSY"));
       
  1732 		}
       
  1733 	User::LeaveIfError(err);
       
  1734 
       
  1735 	TBuf<KCommsDbSvrMaxFieldLength> tsyName;
       
  1736 	tsyName = *tsyField;
       
  1737 
       
  1738 	CleanupStack::PopAndDestroy(3, db); // db, tsyField & globalSettingField
       
  1739 	
       
  1740 	TInt ret(iEtelServer.Connect()); // First connect to the ETel server
       
  1741 	if(ret==KErrNone)
       
  1742 		{
       
  1743 		LOGSERVER1(_L8("Loading TSY")); // Now load the TSY 
       
  1744 		ret=iEtelServer.LoadPhoneModule(tsyName);
       
  1745 		RTelServer::TPhoneInfo phoneInfo;
       
  1746 		if(ret==KErrNone)
       
  1747 			{
       
  1748 			// Determine if TSY supports V2 functionality
       
  1749 			// in event of a problem here assume that it does not
       
  1750 			ret = iEtelServer.IsSupportedByModule(tsyName, KETelExtMultimodeV2, iIsV2Tsy);
       
  1751 			if (ret != KErrNone)
       
  1752 				{
       
  1753 				iIsV2Tsy = EFalse;
       
  1754 				}
       
  1755 
       
  1756 			// Determine if TSY supports V5 functionality
       
  1757  			// in event of a problem here assume that it does not
       
  1758  			ret = iEtelServer.IsSupportedByModule(tsyName, KEtelExtMultimodeV5, iIsV5Tsy);
       
  1759  			if (ret != KErrNone)
       
  1760  				{
       
  1761  				iIsV5Tsy = EFalse;
       
  1762  				}
       
  1763 
       
  1764 			// Determine if TSY supports USIM Apps
       
  1765 			// in event of a problem here assume that it does not
       
  1766 			ret = iEtelServer.IsSupportedByModule(tsyName, KEtelFuncMobileUSIMApplications, iIsUsimAppTsy);
       
  1767 			if (ret != KErrNone)
       
  1768 				{
       
  1769 				iIsUsimAppTsy = EFalse;
       
  1770 				}
       
  1771 
       
  1772 			TInt phoneIndex(0);
       
  1773 			iEtelServer.EnumeratePhones(phoneIndex); // Get total number of phones supported by all currently loaded TSY modules
       
  1774 			while(phoneIndex-->0)
       
  1775 				{
       
  1776 				TName searchTsyName;
       
  1777 				// Check whether this phone belongs to loaded TSY
       
  1778 				if((iEtelServer.GetTsyName(phoneIndex,searchTsyName)==KErrNone) && (searchTsyName.CompareF(tsyName)==KErrNone)) 
       
  1779 					break;
       
  1780 				}
       
  1781 			iEtelServer.GetPhoneInfo(phoneIndex,phoneInfo); // Get information associated with specified phone
       
  1782 
       
  1783 			LOGSERVER1(_L8("Open the phone"));
       
  1784 			ret = iPhone.Open(iEtelServer,phoneInfo.iName); // Open and intialise the phone
       
  1785 			if (ret==KErrNone)
       
  1786 				{
       
  1787 				RPhone::TStatus phoneStatus;
       
  1788 				iPhone.GetStatus(phoneStatus); 
       
  1789 				if(phoneStatus.iMode==RPhone::EModeUnknown) // Check whether phone has already been initialised
       
  1790 					{	
       
  1791 					ret=iPhone.Initialise();
       
  1792 					
       
  1793 					if(ret!=KErrNone)
       
  1794 						{	
       
  1795 						LOGSERVER2(_L8("Phone initialisation failed - closing phone (ret=%d)"), ret);
       
  1796 						iPhone.Close();
       
  1797 						}
       
  1798 					}
       
  1799 
       
  1800 				if(ret==KErrNone) // Do not even try to open SAT if phone not successfully initialised
       
  1801 					{
       
  1802 					TInt retSat=iSat.Open(iPhone);
       
  1803 					if(retSat==KErrNone)
       
  1804 						{
       
  1805 						iIsSatSupported=ETrue; // SAT supported by TSY so proceed with SAT processing
       
  1806 						// Determine if TSY supports V2 SAT - in event of a problem assume that it does not
       
  1807 						ret = iEtelServer.IsSupportedByModule(tsyName, KETelExtSatV2, iIsV2SAT);
       
  1808 						if (ret != KErrNone)
       
  1809 							{
       
  1810 							iIsV2SAT = EFalse;
       
  1811 							}
       
  1812 						}
       
  1813 					else
       
  1814 						{
       
  1815 						LOGSERVER2(_L8("Could not start ETel SAT (retSat=%d)"), retSat);
       
  1816 						iIsSatSupported = EFalse;
       
  1817 						}
       
  1818 					}
       
  1819 				}
       
  1820 			}
       
  1821 		else
       
  1822 			{
       
  1823 			LOGSERVER2(_L8("Could not load the TSY (ret=%d)"), ret);
       
  1824 			}
       
  1825 		}
       
  1826 	else
       
  1827 		{
       
  1828 		LOGSERVER2(_L8("Could not connect to ETel (ret=%d)"), ret);
       
  1829 		}
       
  1830 
       
  1831 	User::LeaveIfError(ret);
       
  1832 	} // CPhoneBookServer::ConnectToEtelL
       
  1833 
       
  1834 
       
  1835 /**
       
  1836  *  Complete an outstanding GetPhoneStoreInfo request.
       
  1837  *
       
  1838  *  @note  Any errors will cause the phonebook setup to be ignored. This puts
       
  1839  *         the phonebook in limbo as it is supported but not usable.
       
  1840  *
       
  1841  *  @param aRetVal        Result of the request.
       
  1842  *  @param aStoreInfo     Phonebook store information containing the phonebook ID.
       
  1843  *  @param aPhonebookUid  Type of the ICC phonebook used internally by the server 
       
  1844  */
       
  1845 void CPhoneBookServer::CompleteGetPhoneStoreInfo(TInt aRetVal, 
       
  1846 											     RMobilePhoneBookStore::TMobilePhoneBookInfoV5& aStoreInfo, 
       
  1847 					 							 TUid aPhonebookUid)
       
  1848 	{
       
  1849 	LOGSERVER4(_L8("CompleteGetPhoneStoreInfo(): retVal=%d phonebook=0x%08x "
       
  1850 				   "Identity=\"%S\""), aRetVal, aPhonebookUid,
       
  1851 				   &aStoreInfo.iIdentity);
       
  1852 
       
  1853 	if (aRetVal == KErrNone)
       
  1854 		{
       
  1855 		//
       
  1856 		// First log the structure as the contents have been the cause of a
       
  1857 		// number of defects so far...
       
  1858 		//		
       
  1859 #ifdef _DEBUG
       
  1860 		TBuf8<RMobilePhone::KMaxMobileNameSize>  nameIn8bit;
       
  1861 		nameIn8bit.Copy(aStoreInfo.iName);
       
  1862 #endif
       
  1863 
       
  1864 		LOGSERVER2(_L8("PhoneBookInfo: iExtensionId=%d"), aStoreInfo.ExtensionId());
       
  1865 		LOGSERVER2(_L8("PhoneBookInfo: iType=%d"), aStoreInfo.iType);
       
  1866 		LOGSERVER2(_L8("PhoneBookInfo: iTotalEntries=%d"), aStoreInfo.iTotalEntries);
       
  1867 		LOGSERVER2(_L8("PhoneBookInfo: iUsedEntries=%d"), aStoreInfo.iUsedEntries);
       
  1868 		LOGSERVER2(_L8("PhoneBookInfo: iCaps=0x%08x"), aStoreInfo.iCaps);
       
  1869 		LOGSERVER2(_L8("PhoneBookInfo: iName=\"%S\""), &nameIn8bit);
       
  1870 
       
  1871 		if (aStoreInfo.ExtensionId() == RMobilePhoneBookStore::KETelMobilePhonebookStoreV1  ||
       
  1872 			aStoreInfo.ExtensionId() == RMobilePhoneBookStore::KETelMobilePhonebookStoreV2  ||
       
  1873 			aStoreInfo.ExtensionId() == RMobilePhoneBookStore::KETelMobilePhonebookStoreV5)
       
  1874 			{
       
  1875 			LOGSERVER2(_L8("PhoneBookInfo: iMaxNumLength=%d"), aStoreInfo.iMaxNumLength);
       
  1876 			LOGSERVER2(_L8("PhoneBookInfo: iMaxTextLength=%d"), aStoreInfo.iMaxTextLength);
       
  1877 			LOGSERVER2(_L8("PhoneBookInfo: iLocation=%d"), (TInt) aStoreInfo.iLocation);
       
  1878 			LOGSERVER2(_L8("PhoneBookInfo: iChangeCounter=%d"), (TInt) aStoreInfo.iChangeCounter);
       
  1879 			LOGSERVER2(_L8("PhoneBookInfo: iIdentity=\"%S\""), &aStoreInfo.iIdentity);
       
  1880 			}
       
  1881 		
       
  1882 		if (aStoreInfo.ExtensionId() == RMobilePhoneBookStore::KETelMobilePhonebookStoreV2  ||
       
  1883 			aStoreInfo.ExtensionId() == RMobilePhoneBookStore::KETelMobilePhonebookStoreV5)
       
  1884 			{
       
  1885 #ifdef _DEBUG
       
  1886 			TBuf8<KMaxName>  phBkModeIn8bit;
       
  1887 			phBkModeIn8bit.Copy(aStoreInfo.iPhBkMode);
       
  1888 #endif
       
  1889 
       
  1890 			LOGSERVER2(_L8("PhoneBookInfo: iPhBkMode=\"%S\""), &phBkModeIn8bit);
       
  1891 			}
       
  1892 		
       
  1893 		if (aStoreInfo.ExtensionId() == RMobilePhoneBookStore::KETelMobilePhonebookStoreV5)
       
  1894 			{
       
  1895 			LOGSERVER2(_L8("PhoneBookInfo: iMaxSecondNames=%d"), aStoreInfo.iMaxSecondNames);
       
  1896 			LOGSERVER2(_L8("PhoneBookInfo: iMaxTextLengthSecondName=%d"), aStoreInfo.iMaxTextLengthSecondName);
       
  1897 			LOGSERVER2(_L8("PhoneBookInfo: iMaxAdditionalNumbers=%d"), aStoreInfo.iMaxAdditionalNumbers);
       
  1898 			LOGSERVER2(_L8("PhoneBookInfo: iMaxNumLengthAdditionalNumber=%d"), aStoreInfo.iMaxNumLengthAdditionalNumber);
       
  1899 			LOGSERVER2(_L8("PhoneBookInfo: iMaxTextLengthAdditionalNumber=%d"), aStoreInfo.iMaxTextLengthAdditionalNumber);
       
  1900 			LOGSERVER2(_L8("PhoneBookInfo: iMaxGroupNames=%d"), aStoreInfo.iMaxGroupNames);
       
  1901 			LOGSERVER2(_L8("PhoneBookInfo: iMaxTextLengthGroupName=%d"), aStoreInfo.iMaxTextLengthGroupName);
       
  1902 			LOGSERVER2(_L8("PhoneBookInfo: iMaxEmailAddr=%d"), aStoreInfo.iMaxEmailAddr);
       
  1903 			LOGSERVER2(_L8("PhoneBookInfo: iMaxTextLengthEmailAddr=%d"), aStoreInfo.iMaxTextLengthEmailAddr);
       
  1904 			}
       
  1905 		
       
  1906 		//
       
  1907 		// Should a TSY return iTotalEntries as 0 for ADN then we are in big trouble and
       
  1908 		// no sync will be possible. It is an error in the TSY so we must panic.
       
  1909 		//
       
  1910 		if (aPhonebookUid == KUidIccGlobalAdnPhonebook  &&
       
  1911 			aStoreInfo.iTotalEntries == 0)
       
  1912 			{
       
  1913 			PhBkSyncPanic(EPhBkSyncPanicGetPhoneStoreInfoError);
       
  1914 			}
       
  1915 		
       
  1916 		//
       
  1917 		// Create the default contacts field structure for this phonebook.
       
  1918 		// These are default settings for all phonebooks regardless of type
       
  1919 		// of ICC.
       
  1920 		//
       
  1921 		RPhoneBookSession::TContactFieldsV3  contactFieldsV3;
       
  1922 		TInt  result;
       
  1923 	
       
  1924 		contactFieldsV3.iNameField.iLength    = aStoreInfo.iMaxTextLength;
       
  1925 		contactFieldsV3.iNameField.iCount     = 1;
       
  1926 		contactFieldsV3.iNameField.iDisplayed = ETrue;
       
  1927 
       
  1928 		contactFieldsV3.iNumberField.iLength    = aStoreInfo.iMaxNumLength;
       
  1929 		contactFieldsV3.iNumberField.iCount     = 1;
       
  1930 		contactFieldsV3.iNumberField.iDisplayed = ETrue;
       
  1931 	
       
  1932 		contactFieldsV3.iIccSlotField.iLength    = -1;
       
  1933 		contactFieldsV3.iIccSlotField.iCount     = 1;
       
  1934 		contactFieldsV3.iIccSlotField.iDisplayed = ETrue;
       
  1935 	
       
  1936 		contactFieldsV3.iPhonebook = aPhonebookUid;
       
  1937 
       
  1938 		if (iICCCaps & RMobilePhone::KCapsUSimAccessSupported)
       
  1939 			{
       
  1940 			//
       
  1941 			// Set up the 3G ICC contact settings.  There are additional fields
       
  1942 			// for ADN and USIM App phonebooks.
       
  1943 			//
       
  1944 			if (aPhonebookUid == KUidIccGlobalAdnPhonebook  || 
       
  1945 				aPhonebookUid == KUidUsimAppAdnPhonebook)
       
  1946 				{
       
  1947 				if (aStoreInfo.ExtensionId()==RMobilePhoneBookStore::KETelMobilePhonebookStoreV5)
       
  1948 					{
       
  1949 			 		contactFieldsV3.iAdditionalNumString.iLength    = aStoreInfo.iMaxNumLengthAdditionalNumber;
       
  1950 			 		contactFieldsV3.iAdditionalNumString.iCount     = aStoreInfo.iMaxAdditionalNumbers;
       
  1951 			 		contactFieldsV3.iAdditionalNumString.iDisplayed = ETrue;
       
  1952 			 
       
  1953 			 		contactFieldsV3.iAdditionalNumAlphaString.iLength    = aStoreInfo.iMaxTextLengthAdditionalNumber;
       
  1954 			 		contactFieldsV3.iAdditionalNumAlphaString.iCount     = aStoreInfo.iMaxAdditionalNumbers;
       
  1955 			 		contactFieldsV3.iAdditionalNumAlphaString.iDisplayed = ETrue;
       
  1956 			 
       
  1957 			 		contactFieldsV3.iGroupField.iLength    = aStoreInfo.iMaxTextLengthGroupName;
       
  1958 			 		contactFieldsV3.iGroupField.iCount     = aStoreInfo.iMaxGroupNames;
       
  1959 			 		contactFieldsV3.iGroupField.iDisplayed = ETrue;
       
  1960 			 
       
  1961 			 		contactFieldsV3.iEmailField.iLength    = aStoreInfo.iMaxTextLengthEmailAddr;
       
  1962 			 		contactFieldsV3.iEmailField.iCount     = aStoreInfo.iMaxEmailAddr;
       
  1963 			 		contactFieldsV3.iEmailField.iDisplayed = ETrue;
       
  1964 			 
       
  1965 			 		contactFieldsV3.iSecondNameField.iLength    = aStoreInfo.iMaxTextLengthSecondName;
       
  1966 			 		contactFieldsV3.iSecondNameField.iCount     = aStoreInfo.iMaxSecondNames;
       
  1967 			 		contactFieldsV3.iSecondNameField.iDisplayed = ETrue;
       
  1968 			 		}
       
  1969 			 	else
       
  1970 			 		{
       
  1971 					contactFieldsV3.iAdditionalNumString.iLength    = aStoreInfo.iMaxTextLength;
       
  1972 					contactFieldsV3.iAdditionalNumString.iCount     = -1;
       
  1973 					contactFieldsV3.iAdditionalNumString.iDisplayed = ETrue;
       
  1974 
       
  1975 					contactFieldsV3.iAdditionalNumAlphaString.iLength    = aStoreInfo.iMaxTextLength;
       
  1976 					contactFieldsV3.iAdditionalNumAlphaString.iCount     = -1;
       
  1977 					contactFieldsV3.iAdditionalNumAlphaString.iDisplayed = ETrue;
       
  1978 
       
  1979 					contactFieldsV3.iGroupField.iLength    = aStoreInfo.iMaxTextLength;
       
  1980 					contactFieldsV3.iGroupField.iCount     = -1;
       
  1981 					contactFieldsV3.iGroupField.iDisplayed = ETrue;
       
  1982 
       
  1983 					contactFieldsV3.iEmailField.iLength    = aStoreInfo.iMaxTextLength;
       
  1984 					contactFieldsV3.iEmailField.iCount     = -1;
       
  1985 					contactFieldsV3.iEmailField.iDisplayed = ETrue;			 		
       
  1986 
       
  1987 					contactFieldsV3.iSecondNameField.iLength    = aStoreInfo.iMaxTextLength;
       
  1988 					contactFieldsV3.iSecondNameField.iCount     = -1;
       
  1989 					contactFieldsV3.iSecondNameField.iDisplayed = ETrue;
       
  1990 			 		}
       
  1991 				}
       
  1992 			}
       
  1993 		
       
  1994 		result = iPhonebookManager->SetContactFields(aPhonebookUid, contactFieldsV3);
       
  1995 		if (result != KErrNone)
       
  1996 			{
       
  1997 			return;
       
  1998 			}
       
  1999 
       
  2000 		//
       
  2001 		// Initialise the Look Up Table...
       
  2002 		//
       
  2003 		result = iPhonebookManager->SetLookUpTableSize(aPhonebookUid, aStoreInfo.iTotalEntries);
       
  2004 		if (result != KErrNone)
       
  2005 			{
       
  2006 			return;
       
  2007 			}
       
  2008 
       
  2009 		//
       
  2010 		// Get the current sync mode. This is used later and also to decide if
       
  2011 		// we need to get the previous phonebook info...
       
  2012 		//
       
  2013 		RPhoneBookSession::TPhonebookSyncMode  syncMode;
       
  2014 		
       
  2015 		result = iPhonebookManager->GetSyncMode(aPhonebookUid, syncMode);
       
  2016 		if (result != KErrNone)
       
  2017 			{
       
  2018 			return;
       
  2019 			}
       
  2020 		
       
  2021 		//
       
  2022 		// Get the previous phonebook info if we need it...
       
  2023 		//
       
  2024 		RMobilePhoneBookStore::TMobilePhoneBookInfoV5  oldPhBkInfo;
       
  2025 
       
  2026 		if (syncMode == RPhoneBookSession::EAutoSameIcc)
       
  2027 			{
       
  2028 			result = iPhonebookManager->GetPhoneBookInfo(aPhonebookUid, oldPhBkInfo);
       
  2029 			if (result != KErrNone)
       
  2030 				{
       
  2031 				return;
       
  2032 				}
       
  2033 			}
       
  2034 		
       
  2035 		//
       
  2036 		// Store the new phonebook info...
       
  2037 		//
       
  2038 		iPhonebookManager->SetPhoneBookInfo(aPhonebookUid, aStoreInfo);
       
  2039 		iPhonebookManager->SetPhBkInfoRetrievedResult(aPhonebookUid, aRetVal);
       
  2040 		
       
  2041 		//
       
  2042 		// If the phonebook is in auto-sync mode then queue a sync request...
       
  2043 		//
       
  2044 		if (syncMode == RPhoneBookSession::EAutoCurrentIcc  ||
       
  2045 		    (syncMode == RPhoneBookSession::EAutoSameIcc  &&  aStoreInfo.iIdentity == oldPhBkInfo.iIdentity))
       
  2046 			{
       
  2047 			QueueAutoSyncRequest(aPhonebookUid);
       
  2048 			}
       
  2049 		}
       
  2050 	else
       
  2051 		{
       
  2052 		//
       
  2053 		// The phonebook is not available or supported.
       
  2054 		//
       
  2055 		iPhonebookManager->SetPhBkInfoRetrievedResult(aPhonebookUid, aRetVal);
       
  2056 
       
  2057 		//
       
  2058 		// If the sync mode is auto-sync current then perform an auto sync in
       
  2059 		// case any entries exist in the database from previous syncs. The
       
  2060 		// sync will fail, but the engine will silently clear the entries out.
       
  2061 		//
       
  2062 		RPhoneBookSession::TPhonebookSyncMode  syncMode;
       
  2063 		TInt  result;
       
  2064 		
       
  2065 		result = iPhonebookManager->GetSyncMode(aPhonebookUid, syncMode);
       
  2066 		if (result == KErrNone  &&
       
  2067 		    syncMode == RPhoneBookSession::EAutoCurrentIcc)
       
  2068 			{
       
  2069 			QueueAutoSyncRequest(aPhonebookUid);
       
  2070 			}
       
  2071 
       
  2072 		}
       
  2073 	} // CPhoneBookServer::CompleteGetPhoneStoreInfo
       
  2074 
       
  2075 
       
  2076 /**
       
  2077  *  Complete an outstanding NotifySecurityEvent request. The Active Notification Base
       
  2078  *  class is responsible for reposting the notification.
       
  2079  *
       
  2080  *  @param aRetVal         Result of the notification request.
       
  2081  *  @param aSecurityEvent  Type of Security Event received.
       
  2082  */
       
  2083 void CPhoneBookServer::CompleteNotifySecurityEvent(TInt aRetVal,
       
  2084 												   RMobilePhone::TMobilePhoneSecurityEvent aSecurityEvent)
       
  2085 	{
       
  2086 	if (aRetVal == KErrNone)
       
  2087 		{
       
  2088 #ifdef _DEBUG
       
  2089 		const char*  KEventNames[23] = {"ENoICCFound", "EICCTerminated",
       
  2090 									    "EPin1Required", "EPuk1Required",
       
  2091 									    "EPin2Required", "EPuk2Required",
       
  2092 									    "EPhonePasswordRequired",
       
  2093 									    "ESPCRequired", "EPin1Verified",
       
  2094 									    "EPin2Verified", "EPuk1Verified",
       
  2095 									    "EPuk2Verified",
       
  2096 									    "EPhonePasswordVerified", "ESPCVerified",
       
  2097 									    "EHiddenKeyRequired", "EHiddenKeyVerified",
       
  2098 									    "EUSIMAppPinRequired", "EUSIMAppPinVerified",
       
  2099 									    "ESecondUSIMAppPinRequired",
       
  2100 									    "ESecondUSIMAppPinVerified",
       
  2101 									    "EUniversalPinRequired",
       
  2102 									    "EUniversalPinVerified",
       
  2103 									    "ESPCChanged"};
       
  2104 #endif
       
  2105 
       
  2106 		LOGSERVER2(_L8("CompleteNotifySecurityEvent(): %s."), KEventNames[aSecurityEvent]);
       
  2107 
       
  2108 		iPhonebookManager->RecordSecurityEvent(aSecurityEvent);
       
  2109 		}
       
  2110 	} // CPhoneBookServer::CompleteNotifySecurityEvent
       
  2111 
       
  2112 
       
  2113 /**
       
  2114  *  Complete an outstanding NotifyLockInfoChange request. The Active Notification Base
       
  2115  *  class is responsible for reposting the notification.
       
  2116  *
       
  2117  *  @param aRetVal    Result of the notification request.
       
  2118  *  @param aLock      Mobile phone lock.
       
  2119  *  @param aLockInfo  Status of the changed lock.
       
  2120  */
       
  2121 void CPhoneBookServer::CompleteNotifyLockInfoChange(TInt aRetVal,
       
  2122 													RMobilePhone::TMobilePhoneLock& aLock,
       
  2123 		                                            RMobilePhone::TMobilePhoneLockInfoV1& aLockInfo)
       
  2124 	{
       
  2125 	if (aRetVal == KErrNone)
       
  2126 		{
       
  2127 #ifdef _DEBUG
       
  2128 		const char*  KStatusNames[4] = {"unknown", "locked", "unlocked", "blocked"};
       
  2129 		const char*  KSettingNames[4] = {"unknown", "enabled", "disabled", "replaced"};
       
  2130 #endif
       
  2131 
       
  2132 		if (aLock == RMobilePhone::ELockICC)
       
  2133 			{
       
  2134 			LOGSERVER3(_L8("Lock Info: PIN1 lock is %s and %s."),
       
  2135 					 KStatusNames[aLockInfo.iStatus], KSettingNames[aLockInfo.iSetting]);
       
  2136 			iPhonebookManager->SetPin1LockStatus(aLockInfo.iStatus);
       
  2137 
       
  2138 			//
       
  2139 			// If the status has become unlocked, then ensure all phonebooks that
       
  2140 			// have previously attempted to be sync'd (and failed) are sync'd now.
       
  2141 			//
       
  2142 			if (aLockInfo.iStatus == RMobilePhone::EStatusUnlocked)
       
  2143 				{
       
  2144 				TInt  phonebookCount(iPhonebookManager->GetPhonebookCount());
       
  2145 
       
  2146 				for(TInt phonebook = 0;  phonebook < phonebookCount;  phonebook++)
       
  2147 					{
       
  2148 					TUid  phonebookUid;
       
  2149 					TInt  result = iPhonebookManager->GetPhonebookUid(phonebook, phonebookUid);
       
  2150 					
       
  2151 					if (result == KErrNone)
       
  2152 						{
       
  2153 						RPhoneBookSession::TSyncState  syncState;
       
  2154 
       
  2155 						result = iPhonebookManager->GetSyncState(phonebookUid, syncState);
       
  2156 			
       
  2157 						if (result == KErrNone  &&
       
  2158 						    syncState != RPhoneBookSession::EUnsynchronised)
       
  2159 							{
       
  2160 							iPhonebookManager->SetSyncState(phonebookUid,
       
  2161 							                                RPhoneBookSession::EUnsynchronised);
       
  2162 							QueueAutoSyncRequest(phonebookUid);
       
  2163 							}
       
  2164 						}
       
  2165 					}
       
  2166 				}
       
  2167 			}
       
  2168 		else if (aLock == RMobilePhone::ELockPin2)
       
  2169 			{
       
  2170 			LOGSERVER3(_L8("Lock Info: PIN2 lock is %s and %s."),
       
  2171 					 KSettingNames[aLockInfo.iStatus], KStatusNames[aLockInfo.iSetting]);
       
  2172 			iPhonebookManager->SetPin2LockStatus(aLockInfo.iStatus);
       
  2173 			}
       
  2174 		else if (aLock == RMobilePhone::ELockHiddenKey)
       
  2175 			{
       
  2176 			LOGSERVER3(_L8("Lock Info: Hidden key lock is %s and %s."),
       
  2177 					 KSettingNames[aLockInfo.iStatus], KStatusNames[aLockInfo.iSetting]);
       
  2178 			iPhonebookManager->SetHiddenKeyLockStatus(aLockInfo.iStatus);
       
  2179 
       
  2180 			if (aLockInfo.iStatus != RMobilePhone::EStatusLockUnknown)
       
  2181 				{
       
  2182 				//
       
  2183 				// If the USIM ADN phonebook is currently synchronised, or
       
  2184 				// being synchronised, then re-sync it.
       
  2185 				//
       
  2186 				RPhoneBookSession::TSyncState  syncState;
       
  2187 				TInt  result;
       
  2188 			
       
  2189 				result = iPhonebookManager->GetSyncState(KUidUsimAppAdnPhonebook,
       
  2190 														 syncState);
       
  2191 			
       
  2192 				if ((result == KErrNone  &&
       
  2193 				    syncState != RPhoneBookSession::EUnsynchronised)  ||
       
  2194 				    IsEngineRequestQueued(ESyncDoSynchronisation,
       
  2195 										  KUidUsimAppAdnPhonebook,
       
  2196 										  ETrue, ETrue))
       
  2197 					{
       
  2198 					QueueAutoSyncRequest(KUidUsimAppAdnPhonebook);
       
  2199 					}
       
  2200 				}
       
  2201 			}
       
  2202 		else if (aLock == RMobilePhone::ELockUSimApp)
       
  2203 			{
       
  2204 			LOGSERVER3(_L8("Lock Info: USim App lock is %s and %s."),
       
  2205 					 KSettingNames[aLockInfo.iStatus], KStatusNames[aLockInfo.iSetting]);
       
  2206 			iPhonebookManager->SetUsimAppLockStatus(aLockInfo.iStatus);
       
  2207 			}
       
  2208 		else if (aLock == RMobilePhone::ELockUniversalPin)
       
  2209 			{
       
  2210 			LOGSERVER3(_L8("Lock Info: USim Universal PIN is %s and %s."),
       
  2211 					 KSettingNames[aLockInfo.iStatus], KStatusNames[aLockInfo.iSetting]);
       
  2212 			iPhonebookManager->SetUsimUniversalPinLockStatus(aLockInfo.iStatus);
       
  2213 			}
       
  2214 		else
       
  2215 			{
       
  2216 			LOGSERVER3(_L8("Lock Info: Unknown lock is %s (%s)."),
       
  2217 					 KStatusNames[aLockInfo.iStatus], KSettingNames[aLockInfo.iSetting]);
       
  2218 			}
       
  2219 		}
       
  2220 	} // CPhoneBookServer::CompleteNotifyLockInfoChange
       
  2221 
       
  2222 
       
  2223 /**
       
  2224  *  Complete an outstanding NotifySATUpdates request. The Active Notification Base
       
  2225  *  class is responsible for reposting the notification.
       
  2226  *
       
  2227  *  @param aRetVal         Result of the notification request.
       
  2228  *  @param aRefreshType    Type of SAT refresh.
       
  2229  *  @param aPhonebookList  List of phonebooks affected the update. 
       
  2230  */
       
  2231 void CPhoneBookServer::CompleteNotifySATUpdates(TInt aRetVal,
       
  2232 												RSat::TRefreshType aRefreshType,
       
  2233 												RArray<TUid>& aPhonebookList)
       
  2234 	{
       
  2235 	LOGSERVER2(_L8("CompleteNotifySATUpdates(): %d"), aRetVal);
       
  2236 
       
  2237 	if (aRetVal == KErrNone)
       
  2238 		{
       
  2239 		//
       
  2240 		// Is a full re-synchronisation needed???
       
  2241 		//
       
  2242 		if (aRefreshType == RSat::EFileChangeNotification  || 
       
  2243 			aRefreshType == RSat::ESimInitFileChangeNotification)
       
  2244 			{
       
  2245 			//
       
  2246 			// Set cache state to unsynchronised for all affected phonebooks
       
  2247 			// from phonebook list and queue new sync requests...
       
  2248 			//
       
  2249 			TInt  phonebookCount(aPhonebookList.Count());
       
  2250 
       
  2251 			for(TInt phonebook = 0;  phonebook < phonebookCount;  phonebook++)
       
  2252 				{
       
  2253 				TUid  phonebookUid = aPhonebookList[phonebook];
       
  2254 				
       
  2255 				iPhonebookManager->SetSyncState(phonebookUid, RPhoneBookSession::EUnsynchronised);
       
  2256 				CompleteNotifyStateChange(phonebookUid);
       
  2257 				iGetPhoneStoreInfo->QueueGetInfoAndSync(phonebookUid);
       
  2258 				}
       
  2259 			}
       
  2260 		else if (aRefreshType == RSat::ESimInitFullFileChangeNotification)
       
  2261 			{
       
  2262 			//
       
  2263 			// Set cache state to unsynchronised for all phonebooks and
       
  2264 			// then sync them all...
       
  2265 			//
       
  2266 			TInt phonebookCount(iPhonebookManager->GetPhonebookCount());
       
  2267 			TUid phonebookUid;
       
  2268 
       
  2269 			for(TInt phonebook = 0; phonebook < phonebookCount; phonebook++)
       
  2270 				{
       
  2271 				TInt  err = iPhonebookManager->GetPhonebookUid(phonebook, phonebookUid);
       
  2272 				
       
  2273 				if (err == KErrNone)
       
  2274 					{
       
  2275 					iPhonebookManager->SetSyncState(phonebookUid,RPhoneBookSession::EUnsynchronised);
       
  2276 					CompleteNotifyStateChange(phonebookUid);
       
  2277 					iGetPhoneStoreInfo->QueueGetInfoAndSync(phonebookUid);
       
  2278 					}
       
  2279 				}
       
  2280 			}
       
  2281 		}
       
  2282 	} // CPhoneBookServer::CompleteNotifySATUpdates
       
  2283 
       
  2284 
       
  2285 /**
       
  2286  *  Complete an outstanding NotifyAppInfoChange request by passing the AID of
       
  2287  *  the currently active  USIM application in the aActiveUsimAID parameter. The
       
  2288  *  Active Notification Base class is responsible for reposting the notification.
       
  2289  *
       
  2290  *  If the Active App has changed and the USIM App phonebook is synchronised (or
       
  2291  *  has attempted to be synchronised) this a re-synchornisation is performed.
       
  2292  *
       
  2293  *  @param aRetVal         Result of the notification request.
       
  2294  *  @param aInitialValue   True if this is the first value, false if it is an update.
       
  2295  *  @param aActiveUsimAID  The AID of the currently active USIM Application.
       
  2296  */
       
  2297 void CPhoneBookServer::CompleteNotifyAppInfoChange(TInt aRetVal,
       
  2298 												   TBool aInitialValue,
       
  2299 												   RMobilePhone::TAID& aActiveUsimAID)
       
  2300 	{
       
  2301 	LOGSERVER2(_L8("CompleteNotifyAppInfoChange(): aRetVal=%d"), aRetVal);
       
  2302 
       
  2303 	if (aRetVal == KErrNone)
       
  2304 		{
       
  2305 		LOGSERVER2(_L8("CompleteNotifyAppInfoChange(): aActiveUsimAID=\"%S\""),
       
  2306 				   &aActiveUsimAID);
       
  2307 
       
  2308 		//
       
  2309 		// Is this the initial value or an update?
       
  2310 		//
       
  2311 		if (aInitialValue)
       
  2312 			{
       
  2313 			iActiveUsimAID = aActiveUsimAID;
       
  2314 			}
       
  2315 		else
       
  2316 			{
       
  2317 			//
       
  2318 			// The App may have been updated, so see if it has changed...
       
  2319 			//
       
  2320 			if (iActiveUsimAID.CompareF(aActiveUsimAID) != 0)
       
  2321 				{
       
  2322 				//
       
  2323 				// If the USIM ADN phonebook is currently synchronised, or being
       
  2324 				// synchronised then re-sync it.
       
  2325 				//
       
  2326 				RPhoneBookSession::TSyncState  syncState;
       
  2327 				TInt  result;
       
  2328 
       
  2329 				result = iPhonebookManager->GetSyncState(KUidUsimAppAdnPhonebook,
       
  2330 														 syncState);
       
  2331 
       
  2332 				if ((result == KErrNone  &&
       
  2333 				    syncState != RPhoneBookSession::EUnsynchronised)  ||
       
  2334 				    IsEngineRequestQueued(ESyncDoSynchronisation,
       
  2335 										  KUidUsimAppAdnPhonebook,
       
  2336 										  ETrue, ETrue))
       
  2337 					{
       
  2338 					QueueAutoSyncRequest(KUidUsimAppAdnPhonebook);
       
  2339 					}
       
  2340 
       
  2341 				iActiveUsimAID = aActiveUsimAID;
       
  2342 				}
       
  2343 			}
       
  2344 		}
       
  2345 	} // CPhoneBookServer::CompleteNotifyAppInfoChange
       
  2346 
       
  2347 
       
  2348 /**
       
  2349  *  Standard Active Object RunError() method, called when the RunL() method
       
  2350  *  leaves, which will be when the CPhoneBookSession::ServiceL() leaves.
       
  2351  *
       
  2352  *  Find the current message and complete it before restarting the server.
       
  2353  *
       
  2354  *  @param aError  Leave code from CPhoneBookSession::ServiceL().
       
  2355  *
       
  2356  *  @return KErrNone
       
  2357  */
       
  2358 TInt CPhoneBookServer::RunError(TInt aError)
       
  2359 	{
       
  2360 	LOGSERVER2(_L8("RunError %d"), aError);
       
  2361 
       
  2362 	//
       
  2363 	// Complete the request with the available error code.
       
  2364 	//
       
  2365 	if (Message().IsNull() == EFalse)
       
  2366 		{
       
  2367 		Message().Complete(aError);
       
  2368 		}
       
  2369 
       
  2370 	//
       
  2371 	// The leave will result in an early return from CServer::RunL(), skipping
       
  2372 	// the call to request another message. So do that now in order to keep the
       
  2373 	// server running.
       
  2374 	//
       
  2375 	ReStart();
       
  2376 
       
  2377 	return KErrNone;
       
  2378 	} // CPhoneBookServer::RunError
       
  2379 
       
  2380 
       
  2381 /**
       
  2382  *  Queues an engine request. The request will be sent to the engine when the
       
  2383  *  engine is not busy.
       
  2384  *
       
  2385  *  @param aPhonebookSyncRequest  Function request to queue.
       
  2386  *  @param aPhonebookUid          Phonebook to perform the request on.
       
  2387  *  @param aContactId             Optional Contact ID parameter.
       
  2388  *  @param aClientSession         Pointer to the client session, or NULL.
       
  2389  *  @param aClientMessage         The client message request.
       
  2390  */
       
  2391 void CPhoneBookServer::QueueEngineRequestL(TPhonebookSyncRequest aPhonebookSyncRequest,
       
  2392 										   TUid aPhonebookUid,
       
  2393 										   TContactItemId aContactId,
       
  2394 										   CPhoneBookSession* aClientSession,
       
  2395 										   const RMessage2& aClientMessage)
       
  2396 	{
       
  2397 	LOGSERVER5(_L8("QueueEngineRequest(): IPC=%d Phonebook=0x%08x Contact=0x%08x "
       
  2398 				   "Session=0x%08x"),
       
  2399 			   aPhonebookSyncRequest, aPhonebookUid, aContactId,
       
  2400 			   (TInt) aClientSession);
       
  2401 
       
  2402 	//
       
  2403 	// Create a new request and append it to the list of requests...
       
  2404 	//
       
  2405 	CSyncEngineRequest*  request = CSyncEngineRequest::NewL(*this, iSyncEngine,
       
  2406 															aPhonebookSyncRequest,
       
  2407 															aPhonebookUid, aContactId,
       
  2408 															aClientSession, aClientMessage);
       
  2409 	CleanupStack::PushL(request);
       
  2410 	iSyncEngineRequestArray.AppendL(request);
       
  2411 	CleanupStack::Pop(request);
       
  2412 	
       
  2413 	//
       
  2414 	// Ensure that the request runs if nothing else is waiting...
       
  2415 	//
       
  2416 	StartNextEngineRequest();
       
  2417 	} // CPhoneBookServer::QueueEngineRequest
       
  2418 
       
  2419 
       
  2420 /**
       
  2421  *  Start the next engine request if one is available and the engine is not
       
  2422  *  busy.
       
  2423  */
       
  2424 void CPhoneBookServer::StartNextEngineRequest()
       
  2425 	{
       
  2426 	LOGSERVER1(_L8("StartNextEngineRequest()"));
       
  2427 
       
  2428 	//
       
  2429 	// If the next request in the queue is not running then start it...
       
  2430 	//
       
  2431 	if (iSyncEngineRequestArray.Count() > 0  &&
       
  2432 	    iSyncEngineRequestArray[0]->IsActive() == EFalse)
       
  2433 		{
       
  2434 		iSyncEngineRequestArray[0]->StartRequest();
       
  2435 		}
       
  2436 	} // CPhoneBookServer::StartNextEngineRequest
       
  2437 
       
  2438 
       
  2439 /**
       
  2440  *  Completes an Engine Request. This method is called be the Engine Request
       
  2441  *  itself when it finishes. This will cause the request to be removed from
       
  2442  *  the queue, and a new request to be started if one is available.
       
  2443  *
       
  2444  *  @param aEngineRequest  Reference to the Engine Request.
       
  2445  */
       
  2446 void CPhoneBookServer::CompleteEngineRequest(CSyncEngineRequest& aEngineRequest)
       
  2447 	{
       
  2448 	LOGSERVER4(_L8("CompleteEngineRequest(): IPC=%d Phonebook=0x%08x "
       
  2449 				   "Session=0x%08x"),
       
  2450 			   aEngineRequest.PhonebookSyncRequest(),
       
  2451 			   aEngineRequest.PhonebookUid(),
       
  2452 			   (TInt) aEngineRequest.ClientSession());
       
  2453 
       
  2454 	//
       
  2455 	// Remove this request from the list...
       
  2456 	//
       
  2457 	TInt  position = iSyncEngineRequestArray.Find(&aEngineRequest);
       
  2458 	
       
  2459 	if (position != KErrNotFound)
       
  2460 		{
       
  2461 		iSyncEngineRequestArray.Remove(position);
       
  2462 		}
       
  2463 	
       
  2464 	//
       
  2465 	// Start any queued requests that can now begin since the engine finished
       
  2466 	// the last request...
       
  2467 	//
       
  2468 	StartNextEngineRequest();
       
  2469 	} // CPhoneBookServer::CompleteEngineRequest
       
  2470 
       
  2471 
       
  2472 /**
       
  2473  *  Cancel a previous engine request. A request that is in progress is cancelled,
       
  2474  *  while a request that has not reached the engine will be deleted from the queue.
       
  2475  *
       
  2476  *  @param aPhonebookSyncRequest  Function request to cancel.
       
  2477  *  @param aPhonebookUid          Phonebook UID used in the request.
       
  2478  *  @param aContactId             Optional Contact ID parameter.
       
  2479  *  @param aClientSession         Pointer to the client session, or NULL.
       
  2480  */
       
  2481 void CPhoneBookServer::CancelEngineRequest(TPhonebookSyncRequest aPhonebookSyncRequest,
       
  2482 										   TUid aPhonebookUid,
       
  2483 										   TContactItemId aContactId,
       
  2484 										   CPhoneBookSession* aClientSession)
       
  2485 	{
       
  2486 	LOGSERVER5(_L8("CancelEngineRequest(): IPC=%d Phonebook=0x%08x Contact=0x%08x "
       
  2487 				   "Session=0x%08x"), aPhonebookSyncRequest, aPhonebookUid,
       
  2488 			   aContactId, (TInt) aClientSession);
       
  2489 
       
  2490 	//
       
  2491 	// Search through the list of engine requests and if we find this request,
       
  2492 	// then cancel it.
       
  2493 	//
       
  2494 	TInt  requestCount(iSyncEngineRequestArray.Count());
       
  2495 
       
  2496 	for (TInt index = 0;  index < requestCount;  index++)
       
  2497 		{
       
  2498 		CSyncEngineRequest*  request = iSyncEngineRequestArray[index];
       
  2499 		
       
  2500 		if (request->PhonebookSyncRequest() == aPhonebookSyncRequest  &&
       
  2501 			request->PhonebookUid() == aPhonebookUid  &&
       
  2502 			request->ContactId() == aContactId  &&
       
  2503 			request->ClientSession() == aClientSession)
       
  2504 			{
       
  2505 			if (request->IsActive())
       
  2506 				{
       
  2507 				//
       
  2508 				// The request is running, so cancel it.
       
  2509 				//
       
  2510 				request->DoCancel();
       
  2511 				}
       
  2512 			else
       
  2513 				{
       
  2514 				//
       
  2515 				// The request never ran so we need to pretend it was cancelled.
       
  2516 				//
       
  2517 				request->iStatus = KErrCancel;
       
  2518 				TRAP_IGNORE(request->CompleteClientRequestL());
       
  2519 				}
       
  2520 
       
  2521 			break;
       
  2522 			}
       
  2523 		}
       
  2524 	} // CPhoneBookServer::CompleteEngineRequest
       
  2525 
       
  2526 
       
  2527 /**
       
  2528  *  Checks if a previous engine request is queued.
       
  2529  *
       
  2530  *  @param aPhonebookSyncRequest   Function request to look for.
       
  2531  *  @param aPhonebookUid           Phonebook UID used in the request.
       
  2532  *  @param aIncludeUserRequests    If true then requests from the client
       
  2533  *                                 should be included in the search.
       
  2534  *  @param aIncludeActiveRequests  If true then currently executing requests
       
  2535  *                                 should be included in the search.
       
  2536  */
       
  2537 TBool CPhoneBookServer::IsEngineRequestQueued(TPhonebookSyncRequest aPhonebookSyncRequest,
       
  2538 											  TUid aPhonebookUid,
       
  2539 											  TBool aIncludeUserRequests,
       
  2540 											  TBool aIncludeActiveRequests)
       
  2541 	{
       
  2542 	LOGSERVER5(_L8("IsEngineRequestQueued(): %d 0x%08x %d %d"),
       
  2543 			   aPhonebookSyncRequest, aPhonebookUid, aIncludeUserRequests,
       
  2544 			   aIncludeActiveRequests);
       
  2545 	
       
  2546 	//
       
  2547 	// Search through the list of engine requests and looking for the request,
       
  2548 	// including active and user requests if required.
       
  2549 	//
       
  2550 	TInt  requestCount(iSyncEngineRequestArray.Count());
       
  2551 
       
  2552 	for (TInt index = 0;  index < requestCount;  index++)
       
  2553 		{
       
  2554 		CSyncEngineRequest*  request = iSyncEngineRequestArray[index];
       
  2555 		
       
  2556 		if (request->PhonebookSyncRequest() == aPhonebookSyncRequest  &&
       
  2557 			request->PhonebookUid() == aPhonebookUid  &&
       
  2558 			(aIncludeUserRequests  ||  request->ClientSession() == NULL)  &&
       
  2559 			(aIncludeActiveRequests  ||  request->IsActive() == EFalse))
       
  2560 			{
       
  2561 			LOGSERVER1(_L8("IsEngineRequestQueued(): Found"));
       
  2562 			return ETrue;
       
  2563 			}
       
  2564 		}
       
  2565 
       
  2566 	LOGSERVER1(_L8("IsEngineRequestQueued(): Not found"));
       
  2567 	return EFalse;
       
  2568 	} // CPhoneBookServer::IsEngineRequestQueued
       
  2569 
       
  2570 
       
  2571 /**
       
  2572  *  Queue an automatic synchronisation to the engine.
       
  2573  *
       
  2574  *  @param aPhonebookUid   Phonebook to synchronise.
       
  2575  */
       
  2576 void CPhoneBookServer::QueueAutoSyncRequest(TUid aPhonebookUid)
       
  2577 	{
       
  2578 	LOGSERVER2(_L8("QueueAutoSyncRequest(): 0x%08x"), aPhonebookUid);
       
  2579 
       
  2580 	//
       
  2581 	// First check if a request has already been made for an auto-sync on the
       
  2582 	// same phonebook (excluding user requests and requests in progress).
       
  2583 	// If a request already exists then we can ignore this request.
       
  2584 	//
       
  2585 	if (IsEngineRequestQueued(ESyncDoSynchronisation, aPhonebookUid,
       
  2586 							  EFalse, EFalse))
       
  2587 		{
       
  2588 		return;
       
  2589 		}
       
  2590 
       
  2591 	//
       
  2592 	// Queue an engine request for a synchronisation...
       
  2593 	//
       
  2594 	TRAPD(err, QueueEngineRequestL(ESyncDoSynchronisation, aPhonebookUid,
       
  2595 						           KNullContactId, NULL, RMessage2()));
       
  2596 	if (err != KErrNone)
       
  2597 		{
       
  2598 		//
       
  2599 		// The request could not be queued!!!
       
  2600 		//
       
  2601 		LOGSERVER2(_L8("QueueAutoSyncRequest(): Error %d"), err);
       
  2602 
       
  2603 		iPhonebookManager->SetLastSyncError(aPhonebookUid, err);
       
  2604 		iPhonebookManager->SetSyncState(aPhonebookUid, RPhoneBookSession::EErrorDuringSync);
       
  2605 
       
  2606 		CompleteNotifyStateChange(aPhonebookUid);
       
  2607 		}
       
  2608 	} // CPhoneBookServer::QueueAutoSyncRequest
       
  2609 
       
  2610 
       
  2611 /**
       
  2612  *  Factory method for producing a CPhoneBookSyncScheduler object. This creates
       
  2613  *  and installs the Active Scheduler object.
       
  2614  *
       
  2615  *  @return Returns a pointer to the CPhoneBookSyncScheduler object or NULL.
       
  2616  */
       
  2617 CPhoneBookSyncScheduler* CPhoneBookSyncScheduler::NewL()
       
  2618 	{
       
  2619 	LOGSERVER1(_L8("CPhoneBookSyncScheduler::NewL()"));
       
  2620 
       
  2621 	CPhoneBookSyncScheduler*  self = new(ELeave) CPhoneBookSyncScheduler();
       
  2622 	CPhoneBookSyncScheduler::Install(self);
       
  2623 
       
  2624 	return self;
       
  2625 	} // CPhoneBookSyncScheduler::NewL
       
  2626 
       
  2627 
       
  2628 /**
       
  2629  *  Standard Active Scheduler Error() method. This is called if any of the
       
  2630  *  RunErrorL() functions leave. Hopefully this should not happen!
       
  2631  *
       
  2632  *  @param aError  Leave code from the RunErrorL() function.
       
  2633  */
       
  2634 void CPhoneBookSyncScheduler::Error(TInt aError) const
       
  2635 	{
       
  2636 #ifdef _DEBUG
       
  2637 	LOGSERVER2(_L8("CPhoneBookSyncScheduler::Error %d"), aError);
       
  2638 #else
       
  2639 	(void) aError;
       
  2640 #endif
       
  2641 
       
  2642 	PhBkSyncPanic(EPhBkSyncPanicUnexpectedLeave);
       
  2643 	} // CPhoneBookSyncScheduler::Error
       
  2644 
       
  2645 
       
  2646 /**
       
  2647  *  Standard constructor.
       
  2648  *
       
  2649  *  @param aServer  Reference to the main server.
       
  2650  */
       
  2651 CPhoneBookSyncStarter::CPhoneBookSyncStarter(CPhoneBookServer& aServer)
       
  2652   : CAsyncOneShot(EPriorityHigh),
       
  2653     iServer(aServer)
       
  2654 	{
       
  2655 	// NOP
       
  2656 	} // CPhoneBookSyncStarter::CPhoneBookSyncStarter
       
  2657 
       
  2658 
       
  2659 /**
       
  2660  *  RunL() for the starter object. This configures the server fully or
       
  2661  *  shuts it down.
       
  2662  */
       
  2663 void CPhoneBookSyncStarter::RunL()
       
  2664 	{
       
  2665 	LOGSERVER2(_L8("CPhoneBookSyncStarter::RunL(): iStatus=%d."), iStatus.Int());
       
  2666 
       
  2667 	//
       
  2668 	// Configure the server...
       
  2669 	//
       
  2670 	TRAPD(configErr, iServer.ConfigureServerL(CPhoneBookServer::EServerConfigurationFull));
       
  2671 	if (configErr != KErrNone)
       
  2672 		{
       
  2673 		LOGSERVER2(_L8("ConfigureServerL() failed with error %d."), configErr);
       
  2674 
       
  2675 		//
       
  2676 		// Shutdown the server in this case, so it can be restarted later.
       
  2677 		//
       
  2678 		TRAP_IGNORE(iServer.ConfigureServerL(CPhoneBookServer::EServerConfigurationNone));
       
  2679 		CActiveScheduler::Stop();
       
  2680 		}
       
  2681 	} // CPhoneBookSyncStarter::RunL
       
  2682 
       
  2683 
       
  2684 /**
       
  2685  *  Perform all server initialisation, in particular creation of the
       
  2686  *  scheduler and server and then run the scheduler.
       
  2687  */
       
  2688 static void RunServerL()
       
  2689 	{
       
  2690 	//
       
  2691 	// Naming the server thread after the server helps to debug panics.
       
  2692 	//
       
  2693 	User::LeaveIfError(User::RenameThread(PHBKSYNC_SERVER_NAME));
       
  2694 
       
  2695 	//	
       
  2696 	// Create a new Active Scheduler...
       
  2697 	//
       
  2698 	CPhoneBookSyncScheduler*  scheduler = CPhoneBookSyncScheduler::NewL();
       
  2699 	CleanupStack::PushL(scheduler);	
       
  2700 	
       
  2701 	//
       
  2702 	// Create a new PhoneBookServer...
       
  2703 	//
       
  2704 	CPhoneBookServer*  server = CPhoneBookServer::NewL();
       
  2705 	CleanupStack::PushL(server);
       
  2706 	
       
  2707 	//
       
  2708 	// Initialisation complete, now signal the client thread...
       
  2709 	//
       
  2710 	LOGSERVER1(_L8("RunServerL(): Meeting Rendezvous..."));
       
  2711 	RProcess::Rendezvous(KErrNone);
       
  2712 
       
  2713 	//
       
  2714 	// Run the server...
       
  2715 	//
       
  2716 	LOGSERVER1(_L8("RunServerL(): Starting server..."));
       
  2717 	CPhoneBookSyncScheduler::Start();
       
  2718 	
       
  2719 	CleanupStack::PopAndDestroy(2, scheduler);
       
  2720 	} // RunServerL
       
  2721 
       
  2722 
       
  2723 /**
       
  2724  *  Server process entry-point.
       
  2725  *
       
  2726  *  @return  KErrNone or a standard Symbian error code.
       
  2727  */
       
  2728 TInt E32Main()
       
  2729 	{
       
  2730 	__UHEAP_MARK;
       
  2731 
       
  2732 	CTrapCleanup* cleanup=CTrapCleanup::New();
       
  2733 	TInt ret(KErrNone);
       
  2734 	if (cleanup)
       
  2735 		{
       
  2736 		TRAP(ret,RunServerL());
       
  2737 		delete cleanup;
       
  2738 		}
       
  2739 	else
       
  2740 		{
       
  2741 		ret = KErrNoMemory;
       
  2742 		}
       
  2743 
       
  2744 	__UHEAP_MARKEND;
       
  2745 	return ret;
       
  2746 	} // E32Main
       
  2747