diff -r 000000000000 -r e686773b3f54 pimprotocols/phonebooksync/Server/phbksyncsess.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pimprotocols/phonebooksync/Server/phbksyncsess.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,951 @@ +// 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: +// Contains method implementations for CPhonebookSession. +// +// + +/** + @file + @internalComponent +*/ + +#include "Phonebook.h" +#include "PhonebookManager.h" +#include "SyncContactICCEntry.h" +#include "phbksyncsvr.h" +#include "phbksyncsess.h" +#include "phbksynclog.h" + + +#ifdef _DEBUG +/** + * Debug text names for the Phonebook Sync IPC Requests. + */ +const char* KPhonebookSyncRequestNames[26] = { + "ESyncDoSynchronisation", "ESyncGetContactFormat", "ESyncGetSyncMode", + "ESyncSetSyncMode", "ESyncDeleteCntFromICC", "ESyncWriteCntToICC", + "ESyncValidateContact", "ESyncUpdateLookupTable", + "ESyncGetPhoneBookId", "ESyncGetCacheState", "ESyncDbgMarkHeap", + "ESyncDbgCheckHeap", "ESyncDbgMarkEnd", "ESyncDbgFailNext", + "ESyncDoSynchronisationCancel", "ESyncDeleteCntFromICCCancel", + "ESyncWriteCntToICCCancel", "ESyncNotifyCacheStateChange", + "ESyncNotifyCacheStateChangeCancel", "ESyncGetLastSyncError", + "ESyncGetNumSlots", "ESyncGetNumFreeSlots", "ESyncGetFreeSlots", + "ESyncGetSlotId", "ESyncFlushInterfaceQueue", "ESyncShutdownServer"}; +#endif + + +/** + * Second phase constructor for sessions. Called by the CServer2 framework + * when a session is created (e.g. a connection is made to the server). + */ +void CPhoneBookSession::CreateL() + { + LOGSESSION1(_L8("CreateL()")); + + Server().AddSessionL(this); + } // CPhoneBookSession::CreateL() + + +/** + * Destructor for session classes. When this is called it indicates that + * a session is closing its connection with the server. + */ +CPhoneBookSession::~CPhoneBookSession() + { + LOGSESSION1(_L8("~CPhoneBookSession()")); + + Server().DropSession(this); + } // CPhoneBookSession::~CPhoneBookSession() + + +/** + * Handle message requests for this session. Leaving is handled by + * CPhoneBookServer::RunError() which reports the error code to the client. + * + * @param aMessage RMessage2 reference which encapsulates a client request. + */ +void CPhoneBookSession::ServiceL(const RMessage2& aMessage) + + { + LOGSESSION4(_L8("ServiceL(): Session=0x%08x IPC=%d (%s)"), + this, aMessage.Function(), + KPhonebookSyncRequestNames[aMessage.Function()]); + LOGSESSIONTIMESTAMP(); + + switch (aMessage.Function()) + { + case ESyncDoSynchronisation: + { + DoSynchronisationL(aMessage); + } + break; + + case ESyncGetContactFormat: + { + GetContactFormatL(aMessage); + } + break; + + case ESyncGetSyncMode: + { + GetSyncModeL(aMessage); + } + break; + + case ESyncSetSyncMode: + { + SetSyncModeL(aMessage); + } + break; + + case ESyncDeleteCntFromICC: + { + DeleteCntFromICCL(aMessage); + } + break; + + case ESyncWriteCntToICC: + { + WriteCntToICCL(aMessage); + } + break; + + case ESyncValidateContact: + { + ValidateContactL(aMessage); + } + break; + + case ESyncUpdateLookupTable: + { + UpdateLookupTableL(aMessage); + } + break; + + case ESyncGetPhoneBookId: + { + GetPhoneBookIdL(aMessage); + } + break; + + case ESyncGetCacheState: + { + GetCacheStateL(aMessage); + } + break; + + case ESyncDbgMarkHeap: + { + DbgMarkHeapL(aMessage); + } + break; + + case ESyncDbgCheckHeap: + { + DbgCheckHeapL(aMessage); + } + break; + + case ESyncDbgMarkEnd: + { + DbgMarkEndL(aMessage); + } + break; + + case ESyncDbgFailNext: + { + DbgFailNextL(aMessage); + } + break; + + case ESyncDoSynchronisationCancel: + { + DoSynchronisationCancelL(aMessage); + } + break; + + case ESyncDeleteCntFromICCCancel: + { + DeleteCntFromICCCancelL(aMessage); + } + break; + + case ESyncWriteCntToICCCancel: + { + WriteCntToICCCancelL(aMessage); + } + break; + + case ESyncNotifyCacheStateChange: + { + NotifyCacheStateChangeL(aMessage); + } + break; + + case ESyncNotifyCacheStateChangeCancel: + { + NotifyCacheStateChangeCancelL(aMessage); + } + break; + + case ESyncGetLastSyncError: + { + GetLastSyncErrorL(aMessage); + } + break; + + case ESyncGetNumSlots: + { + GetNumSlotsL(aMessage); + } + break; + + case ESyncGetNumFreeSlots: + { + GetNumFreeSlotsL(aMessage); + } + break; + + case ESyncGetFreeSlots: + { + GetFreeSlotsL(aMessage); + } + break; + + case ESyncGetSlotId: + { + GetSlotIdL(aMessage); + } + break; + + case ESyncFlushInterfaceQueue: + { + CompleteRequest(aMessage, KErrNone); + } + break; + + case ESyncShutdownServer: + { + ShutdownServerL(aMessage); + } + break; + + default: + { + aMessage.Panic(PHBKSYNC_SERVER_NAME, + EPhBkSyncPanicIllegalFunction); + } + break; + } + } // CPhoneBookSession::ServiceL() + + +/** + * Completes a client request. This function provides a single point of + * message completion which benefits debugging and maintenance. + * + * @param aMessage The RMessage2 client request. + * @param aResult Result of the request. + */ +void CPhoneBookSession::CompleteRequest(const RMessage2& aMessage, + TInt aResult) const + { + LOGSESSION5(_L8("CompleteRequest(): Session=0x%08x " + "IPC=%d (%s) Result=%d"), this, aMessage.Function(), + KPhonebookSyncRequestNames[aMessage.Function()], aResult); + LOGSESSIONTIMESTAMP(); + + if (aMessage.IsNull() == EFalse) + { + aMessage.Complete(aResult); + } + } // CPhoneBookSession::CompleteRequest() + + +/** + * Requests a synchronisation from the server. This is an asynchronous + * request. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DoSynchronisationL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + + Server().DoSynchronisationL(*this, aMessage, phonebookUid); + } // CPhoneBookSession::DoSynchronisationL() + + +/** + * Requests the supported phonebook field formats from the server. This is a + * synchronous request which will be completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetContactFormatL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + + // + // Get the contact format from the server... + // + RPhoneBookSession::TContactFieldsV3 contactFieldsV3; + TInt result; + + result = Server().GetContactFormatL(phonebookUid, contactFieldsV3); + + // + // If the contact format was retrieved from the server, then write it to + // the client. + // + if (result == KErrNone) + { + RPhoneBookSession::TContactFieldsV1::TContactFieldsExtensionId extensionId; + + extensionId = static_cast(aMessage.Int1()); + if (extensionId == RPhoneBookSession::TContactFieldsV1::KPhBkSyncTContactFieldsV1) + { + RPhoneBookSession::TContactFieldsV1 contactFieldsV1; + RPhoneBookSession::TContactFieldsV1Pckg contactFieldsV1Pckg(contactFieldsV1); + + contactFieldsV1 = static_cast(contactFieldsV3); + + aMessage.WriteL(2, contactFieldsV1Pckg); + } + else if (extensionId == RPhoneBookSession::TContactFieldsV1::KPhBkSyncTContactFieldsV2) + { + RPhoneBookSession::TContactFieldsV2 contactFieldsV2; + RPhoneBookSession::TContactFieldsV2Pckg contactFieldsV2Pckg(contactFieldsV2); + + contactFieldsV2 = static_cast(contactFieldsV3); + + aMessage.WriteL(2, contactFieldsV2Pckg); + } + else + { + RPhoneBookSession::TContactFieldsV3Pckg contactFieldsV3Pckg(contactFieldsV3); + + aMessage.WriteL(2, contactFieldsV3Pckg); + } + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetContactFormatL() + + +/** + * Requests the current setting for the Synchronisation Mode from the server. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetSyncModeL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + + // + // Get the sync mode from the server... + // + RPhoneBookSession::TPhonebookSyncMode syncMode; + TInt result; + + result = Server().GetSyncModeL(phonebookUid, syncMode); + + // + // If the sync mode was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckg syncModePckg(syncMode); + + aMessage.WriteL(1, syncModePckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetSyncModeL() + + +/** + * Requests the server to set the sync mode. This is a synchronous request + * which will be completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::SetSyncModeL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + + // + // Set the sync mode via the server... + // + RPhoneBookSession::TPhonebookSyncMode syncMode = static_cast(aMessage.Int1()); + TInt result; + + result = Server().SetSyncModeL(phonebookUid, syncMode); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::SetSyncModeL() + + +/** + * Requests the server to delete a contact from the ICC. This is an + * asynchronous request. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DeleteCntFromICCL(const RMessage2& aMessage) + { + TContactItemId contactItemId = aMessage.Int0(); + + Server().DeleteCntFromICCL(*this, aMessage, contactItemId); + } // CPhoneBookSession::DeleteCntFromICCL() + + +/** + * Requests the server to write a contact to the ICC. This is an asynchronous + * request. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::WriteCntToICCL(const RMessage2& aMessage) + { + // + // Extract the request parameters from aMessage. These are the template ID, + // buffer size, slot number and ICC Entry pointer. + // + RPhoneBookSession::TTemplateAndBufferSize templateIdAndBufferSize; + TInt slotNum; + TPtr8 iccEntryPtr(NULL, 0); + TPckg templateIdAndBufferSizePckg(templateIdAndBufferSize); + TPckg slotNumPckg(slotNum); + + aMessage.ReadL(0, templateIdAndBufferSizePckg); + aMessage.ReadL(1, slotNumPckg); + + // + // Pass the request to the server for further processing. + // + Server().WriteCntToICCL(*this, aMessage, slotNum, + templateIdAndBufferSize.templateId); + } // CPhoneBookSession::WriteCntToICCL() + + +/** + * Requests the server to validate a contact. This is an asynchronous + * request. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::ValidateContactL(const RMessage2& aMessage) + { + TContactItemId contactItemId = aMessage.Int0(); + MContactSynchroniser::TValidateOperation validateOp = static_cast(aMessage.Int1()); + TInt result; + + result = Server().ValidateContactL(contactItemId, validateOp); + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::ValidateContactL() + + +/** + * Requests the server to update its Look Up Table with new contact + * information. This is a synchronous request which will be completed when + * the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::UpdateLookupTableL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TContactItemId contactItemId = aMessage.Int1(); + TInt index = aMessage.Int2(); + TInt result; + + result = Server().UpdateLookupTableL(phonebookUid, contactItemId, index); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::UpdateLookupTableL() + + +/** + * Requests the Phonebook template or group ID from the server for a + * particular phonebook. This is a synchronous request which will be + * completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetPhoneBookIdL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + RPhoneBookSession::TSyncIdType syncIdType = static_cast(aMessage.Int1()); + TContactItemId contactItemId; + TInt result; + + result = Server().GetPhoneBookIdL(phonebookUid, syncIdType, contactItemId); + + // + // If the phonebook ID was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckg contactItemIdPckg(contactItemId); + + aMessage.WriteL(2, contactItemIdPckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetPhoneBookIdL() + + +/** + * Requests the current cache state for a phonebook from the server. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetCacheStateL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + RPhoneBookSession::TSyncState syncState; + TInt result; + + result = Server().GetCacheStateL(phonebookUid, syncState); + + // + // If the phonebook ID was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckgC syncStatePckg(syncState); + + aMessage.WriteL(1, syncStatePckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetCacheStateL() + + +/** + * Requests the server to mark the start of checking the server's and + * engine's heap. This function only works in debug releases and is a + * synchronous request which will be completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DbgMarkHeapL(const RMessage2& aMessage) + { + TInt count = aMessage.Int0(); + TInt result; + + result = Server().DbgMarkHeap(); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::DbgMarkHeapL() + + +/** + * Requests the server to check that the number of allocated cells at the + * current nested level on the server's and engine's heaps are the same as + * the specified value. This function only works for debug builds and is a + * synchronous request which will be completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DbgCheckHeapL(const RMessage2& aMessage) + { + TInt count = aMessage.Int0(); + TInt result; + + result = Server().DbgCheckHeap(count); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::DbgCheckHeapL() + + +/** + * Requests the server to mark the end of checking the server's and + * engines's heap. This function must match an earlier call to + * DbgMarkHeap() and only functions on debug releases. This is a + * synchronous request which will be completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DbgMarkEndL(const RMessage2& aMessage) + { + TInt count = aMessage.Int0(); + TInt result; + + result = Server().DbgMarkEnd(count); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::DbgMarkEndL() + + +/** + * Simulates heap allocation failure for the sever and engine. + * The failure occurs on the next call to new or any of the functions which + * allocate memory from the heap. This is defined only for debug builds and + * is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DbgFailNextL(const RMessage2& aMessage) + { + TInt count = aMessage.Int0(); + TInt result; + + result = Server().DbgFailNext(count); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::DbgFailNextL() + + +/** + * Requests the server to cancel a previous synchronisation request. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DoSynchronisationCancelL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt result; + + result = Server().DoSynchronisationCancelL(*this, phonebookUid); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::DoSynchronisationCancelL() + + +/** + * Requests the server to cancel a previous delete contact request. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::DeleteCntFromICCCancelL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt result; + + result = Server().DeleteCntFromICCCancelL(*this, phonebookUid); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::DeleteCntFromICCCancelL() + + +/** + * Requests the server to cancel a previous write contact request. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::WriteCntToICCCancelL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt result; + + result = Server().WriteCntToICCCancelL(*this, phonebookUid); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::WriteCntToICCCancelL() + + +/** + * Requests the server to post a notification of cache state change. + * This is an asynchronous request which will be completed when the + * cache state changes or the request is canceled. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::NotifyCacheStateChangeL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + + Server().NotifyCacheStateChangeL(*this, aMessage, phonebookUid); + } // CPhoneBookSession::NotifyCacheStateChangeL() + + +/** + * Requests the server to cancel a previous notify cache state change request. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::NotifyCacheStateChangeCancelL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt result; + + result = Server().NotifyCacheStateChangeCancelL(*this, phonebookUid); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::NotifyCacheStateChangeCancelL() + + +/** + * Requests the last sync error for a phonebook from the server. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetLastSyncErrorL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt lastSyncError; + TInt result; + + result = Server().GetLastSyncErrorL(phonebookUid, lastSyncError); + + // + // If the last sync error was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckg lastSyncErrorPckg(lastSyncError); + + aMessage.WriteL(1, lastSyncErrorPckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetLastSyncErrorL() + + +/** + * Requests the current number of slots in a phonebook from the server. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetNumSlotsL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt numSlots; + TInt result; + + result = Server().GetNumSlotsL(phonebookUid, numSlots); + + // + // If the number of slots was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckg numSlotsPckg(numSlots); + + aMessage.WriteL(1, numSlotsPckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetNumSlotsL() + + +/** + * Requests the current number of free slots in a phonebook from the server. + * This is a synchronous request which will be completed when the procedure + * returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetNumFreeSlotsL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt numFreeSlots, result; + + result = Server().GetNumFreeSlotsL(phonebookUid, numFreeSlots); + + // + // If the number of free slots was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckg numFreeSlotsPckg(numFreeSlots); + + aMessage.WriteL(1, numFreeSlotsPckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetNumFreeSlotsL() + + +/** + * Requests a list of the current free slots from the server. This is a + * synchronous request which will be completed when the procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetFreeSlotsL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + + // + // Get the list of free slots from the server... + // + RArray freeSlots; + CleanupClosePushL(freeSlots); + TInt result; + + result = Server().GetFreeSlotsL(phonebookUid, freeSlots); + + // + // If the number of free slots was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TInt numSlots = freeSlots.Count(); + HBufC8* transferBuf = HBufC8::NewLC(sizeof(TInt) * numSlots); + TPtr8 transferBufPtr(transferBuf->Des()); + + RDesWriteStream writeStream(transferBufPtr); + CleanupClosePushL(writeStream); + + for (TInt slot = 0; slot < numSlots; slot++) + { + writeStream.WriteInt32L(freeSlots[slot]); + } + + transferBufPtr.SetLength(sizeof(TInt) * numSlots); + aMessage.WriteL(1, *transferBuf); + + CleanupStack::PopAndDestroy(2, transferBuf); // writeStream & transferBuf + } + + CleanupStack::PopAndDestroy(&freeSlots); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetFreeSlotsL() + + +/** + * Requests the contact ID of the slot in a particular phonebook from the + * server. This is a synchronous request which will be completed when the + * procedure returns. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::GetSlotIdL(const RMessage2& aMessage) + { + TUid phonebookUid = TUid::Uid(aMessage.Int0()); + TInt slotNum = aMessage.Int1(); + TContactItemId contactItemId; + TInt result; + + result = Server().GetSlotIdL(phonebookUid, slotNum, contactItemId); + + // + // If the slot ID was retrieved then write it back to the client. + // + if (result == KErrNone) + { + TPckg contactItemIdPckg(contactItemId); + + aMessage.WriteL(2, contactItemIdPckg); + } + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::GetSlotIdL() + + +/** + * Requests the server to shut down when it no longer has any connected + * sessions. This procedure is only premitted in debug builds for security + * reasons (e.g. to prevent a denial of service attack) and is provided + * for testing purposes. This is a synchronous request which will be + * completed when the procedure returns. The server will shutdown when the + * last session disconnects. + * + * @param aMessage RMessage2 client request. + */ +void CPhoneBookSession::ShutdownServerL(const RMessage2& aMessage) + { + TBool conditional = aMessage.Int0(); + TInt result; + + result = Server().ShutdownServer(conditional); + + // + // Complete the request... + // + CompleteRequest(aMessage, result); + } // CPhoneBookSession::ShutdownServerL() +