pimprotocols/phonebooksync/Client/phbksyncclisess.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimprotocols/phonebooksync/Client/phbksyncclisess.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1150 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Phonebook Synchroniser API Client side implementation. This file implements
+// the methods used to package the client data and pass it to the front-end server
+// for processing.
+// 
+//
+
+/**
+ @file
+ @publishedAll
+ @released
+*/
+
+#include "phbksync.h"
+#include "common.h"
+#include "Phonebook.h"
+#include "PhonebookManager.h"
+#include "SyncContactICCEntry.h"
+#include "phbksyncsvr.h"
+#include "phbksynclog.h"
+
+
+/**
+ *  Phonebook Synchroniser API version.
+ */
+const TInt  KPhonebookSyncMajorVersion = 1;
+const TInt  KPhonebookSyncMinorVersion = 2;
+const TInt  KPhonebookSyncBuildVersion = 1;
+
+
+/**
+ *  Holds any client data that is used in RPhoneBookSession requests. Typically
+ *  this is data for asynchronous requests which need to be repackaged. This is
+ *  currently just the RPhoneBookSession::WriteContact() APIs.
+ *
+ *  Its data used in an asyncronous request, that does not fit into a IPC
+ *  request. E.g. It is bigger that the 4 32-bit numbers, and is not a
+ *  descriptor. It must be put in a descriptor before it can be sent, and
+ *  that memory has to be allocated somewhere on the client side. 
+ *
+ *  The API code also uses this class to ensure BC by keeping the size of R-classes
+ *  constant. Future data can be added to this class as required.
+ */
+class CSyncClientData : public CBase
+	{
+public:
+	static CSyncClientData* NewL();
+	void ConstructL();
+	CSyncClientData();
+	~CSyncClientData();
+
+public:
+    //
+    // The following fields allow a contact mapped in internal format and other
+    // data related to the WriteContact() API call to be streamed across the IPC
+    // boundary.
+    //
+	RPhoneBookSession::TTemplateAndBufferSize  iWrtCntTmpltIdAndBufSize;
+	CSyncContactICCEntry*  iWrtCntEntry;
+	CBufBase*  iWrtCntEntryBuf;
+	TUid  iWrtCntDefaultPhbkUid;
+	TPtrC8  iWrtCntTmpltIdAndBufSizePtr;
+	TPtr8  iWrtCntSlotNumPtr;
+	TPtr8  iWrtCntPhBkIDPtr;
+	TPtr8  iWrtCntEntryBufPtr;
+	};
+
+
+/**
+ *  Start the server process which lives in its own executable and rendezvous with it.
+ *
+ *  @return  KErrNone if successful, or an error code if not.
+ */
+static TInt StartPhBkSyncServer()
+	{
+	LOGCLIENT1(_L8("StartPhBkSyncServer()"));
+	
+	//
+	// Create a new server process. Simultaneous launching of two such
+	// processes should be detected when the second one attempts to
+	// create the server object, failing with KErrAlreadyExists.
+	//		
+	_LIT(KPhBkSyncSvrExeImg, "PHBKSYNCSVREXE.EXE");
+	RProcess server;
+	
+	TInt  ret = server.Create(KPhBkSyncSvrExeImg, KNullDesC);
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+	
+	//
+	// Rendezvous with the server or abort startup...
+	//
+	TRequestStatus  status;
+
+	server.Rendezvous(status);
+	if (status != KRequestPending)
+		{
+		server.Kill(0);
+		}
+	else
+		{
+		server.Resume();
+		}
+	User::WaitForRequest(status);
+
+	//
+	// We can't use the 'exit reason' if the server paniked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone.
+	//
+	if (server.ExitType() == EExitPanic)
+		{
+		ret = KErrGeneral;
+		}
+	else
+		{
+		ret = status.Int();
+		}
+
+	server.Close();
+
+	return ret;
+	} // StartPhBkSyncServer
+
+
+/**
+ *  Standard constructor.
+ */
+EXPORT_C RPhoneBookSession::RPhoneBookSession()
+  : iData(NULL)
+	{
+	// NOP
+	} // RPhoneBookSession::RPhoneBookSession
+
+
+/**
+ *  Connects the client to the Phonebook Synchroniser Server. 
+ *
+ *  This must be used before any of the other methods listed in this API
+ *  section. The first client to call this method will cause the initiation of
+ *  the Phonebook Synchroniser Server within its own executable process.
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::Connect()
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::Connect()"));
+	
+	__ASSERT_ALWAYS(iData == NULL,
+					PhBkSyncPanic(EPhBkSyncPanicHandleNotClosed));
+
+	//
+	// Create a session with the server, but if it doesn't exist then start it and
+	// then create a session.
+	//
+	TInt  result = CreateSession(PHBKSYNC_SERVER_NAME,
+								 TVersion(KPhonebookSyncMajorVersion,
+	                					  KPhonebookSyncMinorVersion,
+	                					  KPhonebookSyncBuildVersion));
+	if (result == KErrNotFound  ||  result == KErrServerTerminated)
+		{
+		result = StartPhBkSyncServer();
+		
+		if(result == KErrNone)
+			{
+			result = CreateSession(PHBKSYNC_SERVER_NAME,
+								   TVersion(KPhonebookSyncMajorVersion,
+	                					    KPhonebookSyncMinorVersion,
+	                					    KPhonebookSyncBuildVersion));
+			}
+		}	
+		
+	if (result == KErrNone)
+		{
+		TRAP(result, iData = CSyncClientData::NewL());
+		}
+
+	//
+	// If the creation of the session fails clean up session data...
+	//
+	if (result != KErrNone)
+		{
+		Close();
+		}
+
+	return result;
+	} // RPhoneBookSession::Connect
+
+
+/**
+ *  Closes the client's session with the Phonebook Synchroniser Server. 
+ *
+ *  @capability None
+ */
+EXPORT_C void RPhoneBookSession::Close()
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::Close()"));
+
+	RSessionBase::Close();
+
+	delete iData;
+	iData = NULL;
+	} // RPhoneBookSession::Close
+
+
+/**
+ *  Returns the current version of the Phonebook Synchroniser Server.
+ *
+ *  @return The version of the Phonebook Synchroniser Server. 
+ *
+ *  @capability None
+ */
+EXPORT_C TVersion RPhoneBookSession::Version() const
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::Version()"));
+
+	return(TVersion(KPhonebookSyncMajorVersion,
+	                KPhonebookSyncMinorVersion,
+	                KPhonebookSyncBuildVersion));
+	} // RPhoneBookSession::Version
+
+
+/**
+ *  Requests the shutdown of the server when the last client disconnects.
+ *  There is no support for immediate shutdown functionality. This API call
+ *  can only be executed if the server is compiled as a debug release.
+ *  
+ *  @param aConditional  If true, subsequent connection requests from any client
+ *                       will be honoured delaying shutdown until they disconnect.
+ *                       If untrue, all subsequent connect requests will be denied.
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability ReadUserData
+ *  @capability WriteUserData 
+ */
+EXPORT_C TInt RPhoneBookSession::ShutdownServer(TBool aConditional)
+	{	
+	LOGCLIENT1(_L8("RPhoneBookSession::ShutdownServer()"));
+
+	return SendReceive(ESyncShutdownServer, TIpcArgs(aConditional));
+	} // RPhoneBookSession::ShutdownServer
+
+
+/**
+ *  Executes a manual synchronisation of the Global/GSM ADN phonebook entries.
+ *
+ *  @param aReqStatus  On completion, KErrNone if successful, a system-wide error 
+ *                     code if not. 
+ *
+ *  @capability ReadUserData
+ *  @capability WriteUserData
+ */
+EXPORT_C void RPhoneBookSession::DoSynchronisation(TRequestStatus& aReqStatus)
+	{
+	DoSynchronisation(aReqStatus, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::DoSynchronisation
+
+
+/**
+ *  Instructs the Phonebook Synchroniser Server to start a manual synchronisation
+ *  of the ICC phonebook specified by the aPhonebook parameter.
+ *
+ *  @param aReqStatus     On completion, KErrNone if successful, a system-wide
+ *						  error code if not. 
+ *  @param aPhonebookUid  TUid of the ICC phonebook to be synchronised.
+ *
+ *  @capability ReadUserData
+ *  @capability WriteUserData
+ */
+EXPORT_C void RPhoneBookSession::DoSynchronisation(TRequestStatus& aReqStatus,
+												   TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::DoSynchronisation"));
+	
+	SendReceive(ESyncDoSynchronisation, TIpcArgs(aPhonebookUid.iUid), aReqStatus);
+	} // RPhoneBookSession::DoSynchronisation
+
+
+/**
+ *  Instructs the Phonebook Synchroniser Server to verify the access to the ICC
+ *  contact item stored in the Contacts database. The server is responsible for
+ *  mapping the UID to the phonebook this item belongs to.
+ *
+ *  @param aOperation  Holds the type of check, search, edit, read.
+ *  @param aId         The contact model UID of the record stored in the database.
+ *
+ *  @return KErrNone if operation was successful, otherwise return error
+ *
+ *  @capability ReadUserData
+ */
+EXPORT_C TInt RPhoneBookSession::ValidateContact(MContactSynchroniser::TValidateOperation aOperation, 
+												 TContactItemId aId)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::ValidateContact"));
+
+	return SendReceive(ESyncValidateContact, TIpcArgs(aId, aOperation));
+	} // RPhoneBookSession::ValidateContact
+
+
+/**
+ *  Writes the contact item to the Global/GSM ADN phonebook. This can be used
+ *  to edit an existing contact or to create a new contact.
+ *
+ *  @param aReqStatus    On completion, KErrNone if successful, a system-wide error 
+ *                       code if not.
+ *  @param aContactItem  The contact item to write to the ICC card.
+ *  @param aSlotNumber   The slot number to write to contact into. If set to
+ *                       KSyncIndexNotSupplied the Phonebook Synchroniser Server
+ *                       will use the first empty slot and aSlotNumber will contain
+ *                       the slot number used on completion.
+ *
+ *  @capability WriteUserData
+ */
+EXPORT_C void RPhoneBookSession::WriteContact(TRequestStatus& aReqStatus,
+                                              CContactICCEntry& aContactItem, 
+											  TInt& aSlotNumber)
+	{
+	__ASSERT_ALWAYS(iData != NULL,
+					PhBkSyncPanic(EPhBkSyncPanicNullHandle));
+
+	//
+	// The dummy phonebook ID value is used as we are the old API and must communicate
+	// the ADN ID to the server. However the server may write it back and thus it must
+	// be a valid memory address after this function finishes (which is before the async
+	// request will complete).
+	//
+	iData->iWrtCntDefaultPhbkUid = KUidIccGlobalAdnPhonebook;
+	
+	WriteContact(aReqStatus, aContactItem, aSlotNumber,
+	             iData->iWrtCntDefaultPhbkUid);
+	} // RPhoneBookSession::WriteContact
+	
+
+/**
+ *  Write the contact item supplied in the aContactItem parameter to the ICC
+ *  phonebook specified by aPhonebookUid.
+ *
+ *  This method is used to edit an existing or write new entry to the ICC phonebook.
+ *  When editing an existing entry the slot number will be supplied in aContactItem,
+ *  whereas for new entries the new slot number will be returned in the aSlotNumber
+ *  parameter. Similarly for new entries the phonebook UID will be returned in the
+ *  aPhonebookUid parameter.
+ *
+ *  @param aReqStatus     On completion, KErrNone if successful, a system-wide error 
+ *                        code if not.
+ *  @param aContactItem   Contacts ICC entry.
+ *  @param aPhonebookUid  UID of the ICC phonebook.
+ *  @param aSlotNumber    Allocated slot number.
+ *
+ *  @capability WriteUserData
+ */
+EXPORT_C void RPhoneBookSession::WriteContact(TRequestStatus& aReqStatus, CContactICCEntry& aContactItem, 
+											  TInt& aSlotNumber, TUid& aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::WriteContact()"));
+
+	//
+	// Check that the sync client data is available and free any previous
+	// buffer.
+	//
+	__ASSERT_ALWAYS(iData != NULL,
+					PhBkSyncPanic(EPhBkSyncPanicNullHandle));
+
+	//
+	// Convert the entry to internal format used by PhBkSync. This is needed
+	// as use of a Contact Database entry can be dependant on a transaction
+	// being open, therefore an independent structure is used. Also a
+	// CContactICCEntry is not streamable whereas the internal format is.
+	//
+	TRAPD(err, iData->iWrtCntEntry->InitialiseFromContactICCEntryL(aContactItem));
+	if (err != KErrNone)
+		{
+		TRequestStatus*  status = &aReqStatus; 
+		User::RequestComplete(status, err);
+		return;
+		}
+
+	if (aSlotNumber != KSyncIndexNotSupplied)
+		{
+		iData->iWrtCntEntry->iSlotNum = aSlotNumber;
+		}
+
+#ifdef _DEBUG
+	iData->iWrtCntEntry->LogSyncContactICCEntry();
+#endif
+
+	//
+	// Stream the entry into a single buffer. This will allow the entry to be
+	// read accoss the IPC boundary.
+	//
+	// Note: The iWrtCntEntryBuf buffer is allocated by StoreL().
+	//
+	if (iData->iWrtCntEntryBuf)
+		{
+		delete iData->iWrtCntEntryBuf;  
+		iData->iWrtCntEntryBuf = NULL;
+		}
+
+	TRAP(err, iData->iWrtCntEntryBuf = iData->iWrtCntEntry->StoreL());
+	if (err != KErrNone)
+		{
+		TRequestStatus*  status = &aReqStatus; 
+		User::RequestComplete(status, err);
+		return;
+		}
+
+	//
+	// Setup the pointers for the transfer of the contact across the IPC
+	// boundary.
+	//
+	iData->iWrtCntTmpltIdAndBufSize.bufferSize = iData->iWrtCntEntryBuf->Size();
+	iData->iWrtCntTmpltIdAndBufSize.templateId = iData->iWrtCntEntry->iTemplateId;
+
+	iData->iWrtCntTmpltIdAndBufSizePtr.Set(reinterpret_cast<const TText8*>(&iData->iWrtCntTmpltIdAndBufSize),
+										   sizeof(RPhoneBookSession::TTemplateAndBufferSize));
+	iData->iWrtCntSlotNumPtr.Set(reinterpret_cast<TText8*>(&aSlotNumber),
+								 sizeof(aSlotNumber), sizeof(aSlotNumber));
+	iData->iWrtCntPhBkIDPtr.Set(reinterpret_cast<TText8*>(&aPhonebookUid),
+								sizeof(aPhonebookUid), sizeof(aPhonebookUid));
+	iData->iWrtCntEntryBufPtr.Set(iData->iWrtCntEntryBuf->Ptr(0));
+
+	TIpcArgs  args(&iData->iWrtCntTmpltIdAndBufSizePtr,
+	               &iData->iWrtCntSlotNumPtr,
+	               &iData->iWrtCntPhBkIDPtr,
+	               &iData->iWrtCntEntryBufPtr);
+
+	SendReceive(ESyncWriteCntToICC, args, aReqStatus);
+
+	//
+	// This function uses the session client data space to store encoded
+	// parameters before they are sent to the front-end server.  This means
+	// that there is a small risk that if another call to WriteContact is made
+	// before this one completes, then the data maybe corrupted.
+	//
+	// To prevent this we issue a synchronous request here. This will ensure
+	// that at a minimum the request is read by the server and pre-processed
+	// such that the data and pointer locations are read and stored inside the
+	// server.
+	//
+	// This leaves only a risk that if the requests are ADN single phonebook
+	// API versions, then the dummy Phonebook ID may be overwritten. This is
+	// of course not a problem as the dummy value is not used.
+	//
+	SendReceive(ESyncFlushInterfaceQueue, TIpcArgs());
+	} // RPhoneBookSession::WriteContact
+
+
+/**
+ *  Deletes the contact item from the ICC card.
+ *
+ *  @param aReqStatus  On completion, KErrNone if successful, a system-wide error 
+ *                     code if not.
+ *  @param aId         The contact item to delete. 
+ *
+ *  @capability WriteUserData
+ */
+EXPORT_C void RPhoneBookSession::DeleteContact(TRequestStatus& aReqStatus, TContactItemId aId)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::DeleteContact()"));
+
+	SendReceive(ESyncDeleteCntFromICC, TIpcArgs(aId), aReqStatus);
+	} // RPhoneBookSession::DeleteContact
+
+
+/**
+ *  Returns information about the supported fields within an ICC phonebook entry. 
+ *
+ *  The TContactFieldFormat type defines the information available for each field 
+ *  and TContactFieldsV1 is a collection of this information for all supported 
+ *  field types. The client can use the field information to tailor its UI so 
+ *  that user can only enter fields with the maximum number of supported characters.
+ *
+ *  The only fields supported by GSM ADN phonebook are the name, number and ICC 
+ *  slot number, so these are the only fields included in TContactFieldsV1.
+ *
+ *  TContactFieldsV2 is used to contain the new USIM phonebook fields.
+ *
+ *  TContactFieldsV3 is an extension of TContactFieldsV2 and contains additional
+ *  information on the fields supported by the USIM phonebooks.
+ *
+ *  @param aContactFields  On return, the packaged TContactFieldsV1/V2/V3
+ *                         is filled with the supported field information.
+ *
+ *  @return KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetContactFormat(TDes8& aContactFields)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetContactFormat()"));
+
+	TUid  phonebook(KUidIccPhonebookNotSpecified);
+
+	TContactFieldsV1Pckg*  contactFieldsV1Pckg = static_cast<TContactFieldsV1Pckg*>(&aContactFields);
+	TContactFieldsV1&  contactFieldsV1 = (*contactFieldsV1Pckg)();
+	TContactFieldsV1::TContactFieldsExtensionId  extensionId = static_cast<TContactFieldsV1::TContactFieldsExtensionId>(contactFieldsV1.ExtensionId());
+	
+	if (extensionId == TContactFieldsV1::KPhBkSyncTContactFieldsV2)
+		{
+		TContactFieldsV2Pckg*  contactFieldsV2Pckg = static_cast<TContactFieldsV2Pckg*>(&aContactFields);
+		TContactFieldsV2&  contactFieldsV2 = (*contactFieldsV2Pckg)();
+		phonebook = contactFieldsV2.iPhonebook;
+		}
+	else if (extensionId == TContactFieldsV1::KPhBkSyncTContactFieldsV3)
+		{
+		TContactFieldsV3Pckg*  contactFieldsV3Pckg = static_cast<TContactFieldsV3Pckg*>(&aContactFields);
+		TContactFieldsV3&  contactFieldsV3 = (*contactFieldsV3Pckg)();
+		phonebook = contactFieldsV3.iPhonebook;
+		}
+	else
+		{
+		//
+		// Phonebook for TContactFieldsV1 is set to Global ADN, as the same
+		// information is set for all phonebooks.
+		//
+		phonebook = KUidIccGlobalAdnPhonebook;
+		}
+
+	return SendReceive(ESyncGetContactFormat, TIpcArgs(phonebook.iUid, extensionId, 
+	                                                   &aContactFields)); 
+	} // RPhoneBookSession::GetContactFormat
+
+
+/**
+ *  Returns the current setting for the synchronisation mode of the Global/GSM ADN
+ *  phonebook, used by the Phonebook Synchroniser Server at start-up to determine
+ *  if the phonebook should be automatically synchronised.
+ *
+ *  @param aSyncMode  On return, the synchronisation mode.
+ *
+ *  @return KErrNone if the setting is successfully returned in aSyncMode, or
+ *          an error code if the setting does not exist or can not be accessed. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetSyncMode(TPhonebookSyncMode& aSyncMode)
+	{
+	return GetSyncMode(aSyncMode, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetSyncMode
+
+
+/**
+ *  Returns the current setting for the Synchonisation Mode of the ICC phonebook
+ *  specified by aPhonebookUid and used by the Phonebook Synchroniser Server at
+ *  start-up to determine if the phonebook should be automatically synchronised.
+ *
+ *  @param aSyncMode      On return Will contain the current synchronisation mode.
+ *  @param aPhonebookUid  TUid of the ICC phonebook
+ *
+ *  @return KErrNone if operation was successful, otherwise return error.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetSyncMode(TPhonebookSyncMode& aSyncMode,
+                                             TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetSyncMode()"));
+
+	TPckg<TPhonebookSyncMode>  syncModePtr(aSyncMode);
+
+	return SendReceive(ESyncGetSyncMode, TIpcArgs(aPhonebookUid.iUid, &syncModePtr));
+	} // RPhoneBookSession::GetSyncMode
+
+
+/**
+ *  Sets a new value for the synchronisation mode of the Global/GSM ADN phonebook, 
+ *  used by the Phonebook Synchroniser Server at start-up to determine its
+ *  synchronisation policy.
+ *
+ *  If the mode is changing to EAutoCurrentIcc and no sync has yet been performed,
+ *  then an automatic sync will be performed.
+ *
+ *  @param aSyncMode  The new synchronisation mode.
+ *
+ *  @return KErrNone if the setting specified by aSyncMode is successfully changed, 
+ *          or an error code if the setting does not exist or can not be accessed.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::SetSyncMode(TPhonebookSyncMode aSyncMode)
+	{
+	return SetSyncMode(aSyncMode, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::SetSyncMode
+
+
+/**
+ *  Set a new value for the Synchonisation Mode of the ICC phonebook specified by aPhonebookUid,
+ *  used by the Phonebook Synchroniser Server at start-up to determine its synchronisation 
+ *  policy.
+ *
+ *  @param aSyncMode      Current synchronisation mode
+ *  @param aPhonebookUid  TUid of the ICC phonebook
+ *
+ *  @return KErrNone if operation was successful, otherwise return error
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::SetSyncMode(TPhonebookSyncMode aSyncMode,
+                                             TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::SetSyncMode()"));
+	
+	return SendReceive(ESyncSetSyncMode, TIpcArgs(aPhonebookUid.iUid,aSyncMode));
+	} // RPhoneBookSession::SetSyncMode
+
+
+/**
+ *  Returns the requested UID for the ID type belonging to the Global/GSM ADN
+ *  phonebook. This is the ID type spedified by aIdType, which can be either the
+ *  template ID or the group ID for an ICC entry belonging to the Global/GSM ADN
+ *  phonebook, depending on the type supplied by aIdType.
+ *
+ *  @param aId      On return, the contact ID.
+ *  @param aIdType  The type of ID requested.
+ *
+ *  @return KErrNone, if the UID is successfully returned or an error code if the 
+ *          UID does not exist or can not be accessed. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetPhoneBookId(TContactItemId& aId, TSyncIdType aIdType)
+	{
+	return GetPhoneBookId(aId, aIdType, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetPhoneBookId
+
+
+/**
+ *  Return either the current group or template ID (depending on the type supplied
+ *  by aIdType) for the ICC entries belonging to the ICC phonebook specified by the
+ *  aPhonebookUid parameter.
+ *
+ *  @param aId            Contacts UID
+ *  @param aPhonebookUid  TUid of the ICC phonebook
+ *  @param aIdType        Type of Contacts UID
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetPhoneBookId(TContactItemId& aId, TSyncIdType aIdType,
+											    TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetPhoneBookId()"));
+
+	TPckg<TContactItemId>  contactItemIdPtr(aId);
+
+	return SendReceive(ESyncGetPhoneBookId,
+	                   TIpcArgs(aPhonebookUid.iUid, aIdType, &contactItemIdPtr));
+	} // RPhoneBookSession::GetPhoneBookId
+
+
+/**
+ *  Updates the Phonebook Synchroniser's look-up table with the new contact ID in
+ *  the Global/GSM ADN phonebook.
+ *
+ *  This function should be called when a new entry has been added to the Contacts
+ *  Database by a client other than the Phonebook Synchroniser Server, so the server
+ *  can know what the UID of the newly added contact was.
+ *
+ *  The Phonebook Synchroniser plug-in should extract the appropriate details from
+ *  the item (e.g. item UID and slot number) and call the Phonebook server to update
+ *  the look-up tables.
+ *
+ *  @param aNewUid   The contact use for the update.
+ *  @param aIccSlot  The ICC slot number to match the Contacts UID.
+ *
+ *  @return KErrNone if the look-up table update succeeded, or an error code (such 
+ *          as KErrArgument) if the operation failed for that ICC slot number. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::UpdateLookuptable(TContactItemId aNewUid, TInt aIccSlot)
+	{
+	return UpdateLookuptable(aNewUid, aIccSlot, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::UpdateLookuptable
+
+
+/**
+ *  Updates the Phonebook Synchroniser's look-up table with the new contact ID in
+ *  the ICC phonebook specified by the aPhonebookUid parameter
+ *
+ *  This function should be called when a new entry has been added to the Contacts
+ *  Database by a client other than the Phonebook Synchroniser Server, so the server
+ *  can know what the UID of the newly added contact was.
+ *
+ *  The Phonebook Synchroniser plug-in should extract the appropriate details from
+ *  the item (e.g. item UID and slot number) and call the Phonebook server to update
+ *  the look-up tables.
+ *
+ *  @param aNewUid        Contact UID number unique per entry
+ *  @param aIccSlot       ICC slot value
+ *  @param aPhonebookUid  Type of ICC phonebook
+ *
+ *  @return KErrNone if operation was successful, otherwise return error
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::UpdateLookuptable(TContactItemId aNewUid, TInt aIccSlot,
+												   TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::UpdateLookuptable()"));
+
+	return SendReceive(ESyncUpdateLookupTable,
+	                   TIpcArgs(aPhonebookUid.iUid, aNewUid, aIccSlot));
+	} // RPhoneBookSession::UpdateLookuptable
+
+
+/**
+ *  Returns the current state of the Phonebook Synchroniser server cache for
+ *  the Global/GSM ADN phonebook.
+ *
+ * @param aState  On return, the state of the phonebook synchroniser cache.
+ *
+ * @return KErrNone if the state is successfully retrieved, or an error code if 
+ *         the server is unable to process the request. 
+ *
+ * @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetPhoneBookCacheState(TSyncState& aState)
+	{
+	return GetPhoneBookCacheState(aState, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetPhoneBookCacheState
+
+
+/**
+ *  Return the current phonebook server cache state for the ICC phonebook
+ *  specified by the aPhonebook parameter.
+ *
+ *  @param aState         Current state of the phonebook cache
+ *  @param aPhonebookUid  Type of ICC phonebook
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetPhoneBookCacheState(TSyncState& aState,
+														TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetPhoneBookCacheState()"));
+
+	TPckg<TSyncState>  statePtr(aState);
+	
+	return SendReceive(ESyncGetCacheState, TIpcArgs(aPhonebookUid.iUid, &statePtr));
+	} // RPhoneBookSession::GetPhoneBookCacheState
+
+
+/**
+ *  Cancels a previously issued asynchronous request on the Global/GSM ADN phonebook. 
+ *
+ *  @param aReqToCancel  The request to be cancelled.
+ *
+ *  @capability None
+ */
+EXPORT_C void RPhoneBookSession::CancelRequest(TPhonebookSyncRequestCancel aReqToCancel)
+	{
+	CancelRequest(aReqToCancel, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::CancelRequest
+
+
+/**
+ *  Cancels a previously issued asynchronous request. The request to be cancelled
+ *  is specified by the aReqToCancel parameter and the ICC phonebook for which the
+ *  request needs to be cancelled is specified by the aPhonebookUid parameter.
+ *
+ *  @param aReqToCancel   Request to be cancelled.
+ *  @param aPhonebookUid  UID of the ICC phonebook.
+ *
+ *  @capability ReadUserData
+ *  @capability WriteUserData
+ */
+EXPORT_C void RPhoneBookSession::CancelRequest(TPhonebookSyncRequestCancel aReqToCancel,
+											   TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::CancelRequest()"));
+
+	switch (aReqToCancel)
+		{
+		case EDoSynchronisationCancelClient:
+			{
+			SendReceive(ESyncDoSynchronisationCancel, TIpcArgs(aPhonebookUid.iUid));
+			}
+			break;
+
+		case ESyncDeleteCntFromICCCancelClient:
+			{
+			SendReceive(ESyncDeleteCntFromICCCancel, TIpcArgs(aPhonebookUid.iUid));
+			}
+			break;
+
+		case ESyncWriteCntToICCCancelClient:
+			{
+			SendReceive(ESyncWriteCntToICCCancel, TIpcArgs(aPhonebookUid.iUid));
+			}
+			break;
+
+		case ESyncNotifyCacheStateChangeCancelClient:
+			{
+			SendReceive(ESyncNotifyCacheStateChangeCancel, TIpcArgs(aPhonebookUid.iUid));
+			}
+			break;
+
+		default:
+			{
+			PhBkSyncPanic(EPhBkSyncPanicCancelSyncReqError);
+			}
+			break;
+		}
+	} // RPhoneBookSession::CancelRequest
+
+
+/**
+ *  Returns the last server cache sync error for the Global/GSM ADN phonebook. 
+ *
+ *  @param aError  Last server cache sync error
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetLastSyncError(TInt& aError)
+	{
+	return GetLastSyncError(aError, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetLastSyncError
+
+
+/**
+ *  Return the last server cache sync error for the requested phonebook.
+ *
+ *  @param aError         Last server cache sync error.
+ *  @param aPhonebookUid  UID of the ICC phonebook.
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetLastSyncError(TInt& aError,
+												  TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetLastSyncError()"));
+
+	TPckg<TInt>  errorPtr(aError);
+
+	return SendReceive(ESyncGetLastSyncError,
+	                   TIpcArgs(aPhonebookUid.iUid, &errorPtr));
+	} // RPhoneBookSession::GetLastSyncError
+
+
+/**
+ *  Registers the notification for a change in the Global/GSM ADN phonebook cache
+ *  state.
+ *
+ *  @note The client should call GetPhoneBookCacheState() in order to get the new 
+ *        state of the synchroniser.
+ *
+ *  @param aReqStatus  On completion, KErrNone if successful, a system-wide error 
+ *                     code if not.
+ *
+ *  @capability None
+ */
+EXPORT_C void RPhoneBookSession::NotifyPhBkCacheStateChange(TRequestStatus& aReqStatus)
+	{
+	NotifyPhBkCacheStateChange(aReqStatus, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::NotifyPhBkCacheStateChange
+
+
+/**
+ *  Registers the notification for a change in the Phone book cache state.
+ *
+ *  @note  The client should call GetPhoneBookCacheState() in order to get the new 
+ *  state of the synchroniser.
+ *
+ *  @param aReqStatus     On completion, KErrNone if successful, a system-wide error 
+ *                        code if not.
+ *  @param aPhonebookUid  UID of the ICC phonebook.
+ *
+ *  @capability None
+ */
+EXPORT_C void RPhoneBookSession::NotifyPhBkCacheStateChange(TRequestStatus& aReqStatus,
+                                                            TUid aPhonebookUid)
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::NotifyPhBkCacheStateChange()"));
+
+	SendReceive(ESyncNotifyCacheStateChange, TIpcArgs(aPhonebookUid.iUid), aReqStatus);
+	} // RPhoneBookSession::NotifyPhBkCacheStateChange
+
+
+/**
+ *  Gets the total number of slots on the Global/GSM ADN phonebook.
+ *
+ *  @param aNumSlots  The number of slots.
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetNumSlots(TInt& aNumSlots) const
+    {
+	return GetNumSlots(aNumSlots, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetNumSlots
+
+
+/**
+ *  Gets the total number of slots on the specified ICC phonebook.
+ *
+ *  @param aNumSlots      The number of slots.
+ *  @param aPhonebookUid  Type of ICC phonebook
+ *
+ *  @return  KErrNone if successful, a system-wide error code if not. 
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetNumSlots(TInt& aNumSlots,
+											 TUid aPhonebookUid) const
+    {
+	LOGCLIENT1(_L8("RPhoneBookSession::GetNumSlots()"));
+
+	TPckg<TInt>  numSlotsPtr(aNumSlots);
+
+	return SendReceive(ESyncGetNumSlots, TIpcArgs(aPhonebookUid.iUid, &numSlotsPtr));
+	} // RPhoneBookSession::GetNumSlots
+
+
+/**
+ *  Get the slots that are free in the Global/GSM ADN phonebook.
+ *
+ *  @param aFreeSlots  On return, an array of slots numbers that are free.
+ *
+ *  @capability None
+ */
+EXPORT_C void RPhoneBookSession::GetFreeSlotsL(RArray<TInt>& aFreeSlots) const
+	{
+	GetFreeSlotsL(aFreeSlots, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetFreeSlotsL
+
+
+/**
+ *  Get the slots that are free in the requested phonebook.
+ *
+ *  @param aFreeSlots     On return, an array of slots numbers that are free.
+ *  @param aPhonebookUid  Type of ICC phonebook
+ *
+ *  @capability None
+ */
+EXPORT_C void RPhoneBookSession::GetFreeSlotsL(RArray<TInt>& aFreeSlots,
+											   TUid aPhonebookUid) const
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetFreeSlotsL"));
+
+	aFreeSlots.Reset();
+
+	//
+	// Get the number of free slots available...
+	//
+	TInt  numFreeSlots;
+	TPckg<TInt>  numFreeSlotsPtr(numFreeSlots);
+	
+	TIpcArgs args(aPhonebookUid.iUid,&numFreeSlotsPtr);
+	User::LeaveIfError(SendReceive(ESyncGetNumFreeSlots,
+	                               TIpcArgs(aPhonebookUid.iUid, &numFreeSlotsPtr)));
+
+	//
+	// Now read back the data about each slot...
+	//
+	HBufC8*  buf = HBufC8::NewLC(sizeof(TInt) * numFreeSlots);
+	TPtr8  bufPtr(buf->Des());
+	
+	User::LeaveIfError(SendReceive(ESyncGetFreeSlots,
+	                               TIpcArgs(aPhonebookUid.iUid, &bufPtr)));
+
+	RDesReadStream  readStream(*buf);
+	CleanupClosePushL(readStream);
+	
+	for (TInt slot =0;  slot < numFreeSlots;  slot++)
+		{
+		User::LeaveIfError(aFreeSlots.Append(readStream.ReadInt32L()));
+		}
+
+	CleanupStack::PopAndDestroy(2, buf); // readStream, buf
+	} // RPhoneBookSession::GetFreeSlotsL
+
+
+/**
+ *  Get the Contacts UID of a particular slot in the Global/GSM ADN phonebook.
+ *
+ *  @param aSlot  The slot number on which the request is made.
+ *  @param aId    The contact Id of the slot number.
+ *
+ *  @return KErrNotFound if the UID is not found.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetSlotId(TInt aSlot, TContactItemId& aId) const
+	{
+	return GetSlotId(aSlot, aId, KUidIccGlobalAdnPhonebook);
+	} // RPhoneBookSession::GetSlotId
+
+
+/**
+ *  Get the Contacts UID of a particular slot in the requested phonebook.
+ *
+ *  @param aSlot          The slot number on which the request is made.
+ *  @param aId            The contact Id of the slot number.
+ *  @param aPhonebookUid  Type of ICC phonebook
+ *
+ *  @return KErrNotFound if the UID is not found.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::GetSlotId(TInt aSlot, TContactItemId& aId,
+										   TUid aPhonebookUid) const
+	{
+	LOGCLIENT1(_L8("RPhoneBookSession::GetSlotId()"));
+	
+	TPckg<TContactItemId>  contactItemPtr(aId);
+	
+	return SendReceive(ESyncGetSlotId,
+	                   TIpcArgs(aPhonebookUid.iUid,aSlot, &contactItemPtr));
+	} // RPhoneBookSession::GetSlotId
+
+
+/**
+ *  Set a heap mark in the Phonebook Sync Server and Background Sync Engine
+ *  threads.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::__DbgMarkHeap()
+	{
+	TIpcArgs args(TIpcArgs::ENothing);
+
+	return SendReceive(ESyncDbgMarkHeap, args);
+	} // RPhoneBookSession::__DbgMarkHeap
+
+
+/**
+ *  Performs a heap mark check in the Phonebook Sync Server and Background
+ *  Sync Engine threads.
+ *
+ *  @param aCount  The number of heap cells expected to be allocated at
+ *                 the current nest level.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::__DbgCheckHeap(TInt aCount)
+	{
+	TIpcArgs args(aCount);
+
+	return SendReceive(ESyncDbgCheckHeap, args);
+	} // RPhoneBookSession::__DbgCheckHeap
+
+
+/**
+ *  Perfom a heap mark end check in the Phonebook Sync Server and Background
+ *  Sync Engine threads.
+ *
+ *  @param aCount  The number of heap cells expected to remain allocated
+ *                 at the current nest level.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::__DbgMarkEnd(TInt aCount)
+	{
+	TIpcArgs args(aCount);
+
+	return SendReceive(ESyncDbgMarkEnd, args);
+	} // RPhoneBookSession::__DbgMarkEnd
+
+
+/**
+ *  Set a heap fail next condition in the Phonebook Sync Server and
+ *  Background Sync Engine threads.
+ *
+ *  @param aCount  Determines when the allocation will fail.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt RPhoneBookSession::__DbgFailNext(TInt aCount)
+	{
+	TIpcArgs args(aCount);
+
+	return SendReceive(ESyncDbgFailNext, args);
+	} // RPhoneBookSession::__DbgFailNext
+
+
+/**
+ *  This method creates the RPhoneBookSession CPhoneBookSyncData object which is
+ *  used to store temporary data required by some asynchonous requests. 
+ *
+ *  @return Pointer to newly created CPhoneBookSyncData object.
+ */
+CSyncClientData* CSyncClientData::NewL()
+	{
+	CSyncClientData*  syncClientData = new (ELeave) CSyncClientData();
+	CleanupStack::PushL(syncClientData);
+	syncClientData->ConstructL();
+	CleanupStack::Pop(syncClientData);
+
+	return syncClientData;
+	} // CSyncClientData::NewL
+
+
+/**
+ *  Second phase constructor.
+ */
+void CSyncClientData::ConstructL()
+	{
+	iWrtCntEntry = CSyncContactICCEntry::NewL();
+	} // CSyncClientData::ConstructL
+
+
+/**
+ *  Default constructor.
+ */
+CSyncClientData::CSyncClientData()
+  : iWrtCntTmpltIdAndBufSizePtr(NULL, 0),
+    iWrtCntSlotNumPtr(NULL, 0),
+    iWrtCntPhBkIDPtr(NULL, 0),
+    iWrtCntEntryBufPtr(NULL, 0)
+	{
+	// NOP
+	} // CSyncClientData::CSyncClientData
+	
+
+/**
+ *  Destructor.
+ */
+CSyncClientData::~CSyncClientData()
+	{
+	delete iWrtCntEntry;
+	delete iWrtCntEntryBuf;
+	} // CSyncClientData::~CSyncClientData
+
+