--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pimprotocols/phonebooksync/Server/SyncContactsWithICC.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,833 @@
+// 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 the Active Object classes used by the Phonebook
+// Synchroniser.
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "common.h"
+#include "Phonebook.h"
+#include "PhonebookManager.h"
+#include "SyncContactICCEntry.h"
+#include "phbksynclog.h"
+#include "phbksyncsvr.h"
+#include "SyncEngineSession.h"
+#include "SyncEngineServer.h"
+#include "phbksyncsess.h"
+#include "SyncContactsWithICC.h"
+
+
+/**
+ * Number of retries to read the ICC in an ICC multiple read operation.
+ */
+const TInt KMaxICCReadRetryCnt = 1;
+
+
+/**
+ * Delay for retry (will be multiplied by an increasing factor).
+ */
+const TInt KReadRetryDelayBase = 100000;
+
+
+
+/**
+ * Static factory method used to create a CSyncContactsWithICC object.
+ *
+ * @param aSession Reference to the engine session.
+ * @param aPhonebookManager Reference to the Phonebook Manager which stores
+ * all the phonebook parameters.
+ * @param aDb Reference to the database.
+ * @param aPhone Handle to the phone object.
+ * @param aPhonebookUid Phonebook UID for the contact to be deleted from.
+ * @param aClientMessage Handle to the engine message request.
+ */
+CSyncContactsWithICC* CSyncContactsWithICC::NewL(CSyncEngineSession& aSession,
+ CPhoneBookManager& aPhoneBookManager,
+ CContactDatabase& aDb,
+ RMobilePhone& aPhone,
+ TUid aPhonebookUid,
+ const RMessage2& aClientMessage)
+ {
+ CSyncContactsWithICC* self = new(ELeave) CSyncContactsWithICC(aSession,
+ aPhoneBookManager,
+ aDb,
+ aPhone,
+ aPhonebookUid,
+ aClientMessage);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+
+ return self;
+ } // CSyncContactsWithICC::NewL
+
+
+/**
+ * Standard constructor.
+ *
+ * @param aSession Reference to the engine session.
+ * @param aPhonebookManager Reference to the Phonebook Manager which stores
+ * all the phonebook parameters.
+ * @param aDb Reference to the database.
+ * @param aPhone Handle to the phone object.
+ * @param aPhonebookUid Phonebook UID for the contact to be deleted from.
+ * @param aClientMessage Handle to the engine message request.
+ */
+CSyncContactsWithICC::CSyncContactsWithICC(CSyncEngineSession& aSession,
+ CPhoneBookManager& aPhonebookManager,
+ CContactDatabase& aDb,
+ RMobilePhone& aPhone,
+ TUid aPhonebookUid,
+ const RMessage2& aClientMessage)
+ : CActive(EPriorityNormal),
+ iSession(aSession),
+ iPhonebookManager(aPhonebookManager),
+ iDb(aDb),
+ iPhone(aPhone),
+ iPhonebookUid(aPhonebookUid),
+ iClientMessage(aClientMessage),
+ iState(ESyncContactsWithICCStateIdle),
+ iPhonebookDataPtr(NULL,0),
+ iNumOfEntries(1),
+ iSlotNum(1)
+ {
+ // NOP
+ } // CSyncContactsWithICC::CSyncContactsWithICC
+
+
+/**
+ * Standard destructor. This will cancel any pending active requests.
+ */
+CSyncContactsWithICC::~CSyncContactsWithICC()
+ {
+ LOGACTIVE1(_L8("~CSyncContactsWithICC()"));
+
+ Cancel();
+
+ delete iPhonebookData;
+ iUnconfirmedEntries.Close();
+ iTimer.Close();
+ } // CSyncContactsWithICC::~CSyncContactsWithICC
+
+
+/**
+ * Second phase constructor.
+ */
+void CSyncContactsWithICC::ConstructL()
+ {
+ LOGACTIVE1(_L8("CSyncContactsWithICC::ConstructL()"));
+
+ //
+ // Create the phonebook data buffer.
+ //
+ iPhonebookData = HBufC8::NewL(KPBDataClientHeap);
+ iPhonebookDataPtr.Set(const_cast<unsigned char*>(iPhonebookData->Ptr()), 0, KPBDataClientHeap);
+
+ //
+ // Obtain a few bits of info now to save time later...
+ //
+ User::LeaveIfError(iPhonebookManager.GetPhoneBookInfo(iPhonebookUid, iPhBkInfo));
+ User::LeaveIfError(iPhonebookManager.GetPhoneBookStore(iPhonebookUid, iPhone, iPhonebookStore));
+
+ //
+ // Create a timer for use later if needed...
+ //
+ iTimer.CreateLocal();
+
+ CActiveScheduler::Add(this);
+ } // CSyncContactsWithICC::ConstructL
+
+
+/**
+ * Begin synchronising the ICC phonebook into the Contacts Database. This
+ * function begins the process be ensuring the Look-Up Table is upto date
+ * with the information from the Contacts DB. Any contact entires that are
+ * stored outside the slot range of the ICC (e.g. entries from previous ICCs)
+ * are removed.
+ */
+void CSyncContactsWithICC::SyncContactsWithICCL()
+ {
+ LOGACTIVE1(_L8("CSyncContactsWithICC::SyncContactsWithICCL()"));
+
+ //
+ // Check that we are not in use!
+ //
+ if (iState != ESyncContactsWithICCStateIdle)
+ {
+ PhBkSyncPanic(EPhBkSyncPanicDoMultipleReadError);
+ }
+
+ //
+ // Fetch all current database entries into the Look-Up Table. Also we
+ // need to delete all entires outside the size of the phonebook. Start by
+ // getting the size of the phonebook and clearing the current table data.
+ //
+ TInt phonebookSize;
+
+ User::LeaveIfError(iPhonebookManager.GetLookUpTableSize(iPhonebookUid,
+ phonebookSize));
+ User::LeaveIfError(iPhonebookManager.ClearLookUpTable(iPhonebookUid));
+
+ //
+ // Get the Group ID to search for entries. If no ID exists then the
+ // database does not contain any entries.
+ //
+ TContactItemId groupId;
+
+ User::LeaveIfError(iPhonebookManager.GetGroupId(iPhonebookUid, groupId));
+
+
+ //
+ // Populate the lookup table with entries from the contacts database...
+ //
+ if (groupId != KNullContactId && groupId != KGoldenTemplateId)
+ {
+ CContactItem* group = iDb.ReadContactLC(groupId);
+ const CContactIdArray* members = static_cast<CContactGroup*>(group)->ItemsContained();
+ const TInt count = members->Count();
+
+ TContactTextDefItem iccSlotFieldType(KUidContactFieldICCSlot);
+ CContactTextDef* iccSlotFieldTextDef = CContactTextDef::NewLC();
+ iccSlotFieldTextDef->AppendL(iccSlotFieldType);
+
+ for (TInt item = 0; item < count; item++)
+ {
+ //
+ // Read the item from the database and add to the Look-Up Table.
+ // The state is unconfirmed until the synchronisation is complete.
+ //
+ TBuf<KTemplateNumberLength> iccSlotField;
+
+ iDb.ReadContactTextDefL((*members)[item], iccSlotField,
+ iccSlotFieldTextDef);
+ TLex input(iccSlotField);
+ TInt slotNum = 0;
+ input.Val(slotNum);
+
+ //
+ // Delete entries that are in slots exceeding the ICC slot range,
+ // otherwise add them to the Look Up Table.
+ //
+ if (slotNum > phonebookSize)
+ {
+ iDb.DeleteContactL((*members)[item]);
+ }
+ else
+ {
+ User::LeaveIfError(iPhonebookManager.UpdateEntryInTable(iPhonebookUid,
+ slotNum,
+ (*members)[item],
+ ESlotUnconfirmed));
+ }
+ }
+
+ CleanupStack::PopAndDestroy(2, group);
+ }
+
+ //
+ // Now begin the process of reading entries and writting them to the database.
+ //
+ ReadICCEntries();
+ } // CSyncContactsWithICC::SyncContactsWithICCL
+
+
+/**
+ * Issues a read of one or more ICC entries.
+ */
+void CSyncContactsWithICC::ReadICCEntries()
+ {
+ LOGACTIVE1(_L8("CSyncContactsWithICC::ReadICCEntries()"));
+
+ //
+ // Now issue the ICC read and set the object Active...
+ //
+ iPhonebookStore.Read(iStatus, iSlotNum, 1, iPhonebookDataPtr);
+ iState = ESyncContactsWithICCStateWaitForRead;
+ iDbAccessRetryCount=0;
+ iICCReadRetryCount=0;
+ SetActive();
+
+ LOGACTIVETIMESTAMP();
+ } // CSyncContactsWithICC::ReadICCEntries
+
+
+/**
+ * Standard Active Object RunL() method to process the various sync requests.
+ */
+void CSyncContactsWithICC::RunL()
+ {
+ LOGACTIVE2(_L8("CSyncContactsWithICC::RunL() iStatus=%d)"),
+ iStatus.Int());
+
+ switch (iState)
+ {
+ case ESyncContactsWithICCStateWaitForRead:
+ {
+ //
+ // If the request was completed, cancelled or no more entries were found...
+ //
+ if (iStatus.Int() == KErrNone ||
+ iStatus.Int() == KErrCancel ||
+ iStatus.Int() == KErrNotFound)
+ {
+ TInt ret(iStatus.Int());
+
+ iICCReadRetryCount=0;
+
+ //
+ // Now decode received phonebook data and store it in Contacts DB...
+ //
+ TRAPD(decodeErr, DecodeICCAndStoreToDbL(iSlotNum, iReceivedEntries));
+ if (decodeErr != KErrNone)
+ {
+ iSession.Server().RollbackIccTransaction();
+
+ if (iDbAccessRetryCount < KMaxDbAccessRetryCount &&
+ (decodeErr == KErrInUse || decodeErr == KErrLocked))
+ {
+ iDbAccessRetryCount++;
+ LOGACTIVE2(_L8("iDbAccessErrorCount is %d"),iDbAccessRetryCount);
+
+ iTimer.After(iStatus, KReadRetryDelayBase*iDbAccessRetryCount);//increase the delay each time
+ SetActive();
+ LOGACTIVETIMESTAMP();
+ }
+ else
+ {
+ iSession.Server().CompleteDoSync(decodeErr);
+ }
+
+ return;
+ }
+
+ iDbAccessRetryCount = 0; // reset the DB retry counter
+
+ //
+ // Have we finished reading yet?
+ //
+ if ((iPhBkInfo.iUsedEntries < 0 || iReceivedEntries < iPhBkInfo.iUsedEntries) &&
+ iSlotNum < iPhBkInfo.iTotalEntries)
+ {
+ //
+ // Increment the slot number and read some more...
+ //
+ iSlotNum++;
+ ReadICCEntries();
+ }
+ else
+ {
+ //
+ // All entries have been read. It is okay to not find an
+ // entry in the case where the TSY could not tell you how
+ // many entries were used. If there was an error return now.
+ //
+ if (ret != KErrNone && ret != KErrNotFound)
+ {
+ iState = ESyncContactsWithICCStateIdle;
+ iSession.Server().CompleteDoSync(ret);
+ return;
+ }
+
+ //
+ // Request the list of unconfirmed entries to remove...
+ //
+ TInt result;
+
+ result = iPhonebookManager.GetMatchingEntries(iPhonebookUid,
+ ESlotUnconfirmed,
+ iUnconfirmedEntries);
+ if (result != KErrNone)
+ {
+ iSession.Server().CompleteDoSync(result);
+ return;
+ }
+
+ //
+ // Yield and continue processing in the next RunL call.
+ //
+ iState = ESyncContactsWithICCStateRemoveUnconfirmedEntries;
+ YieldToOtherActiveObjects();
+ }
+ }
+ else
+ {
+ if (iICCReadRetryCount < KMaxICCReadRetryCnt)
+ {
+ iICCReadRetryCount++;
+ iPhonebookDataPtr.Zero();
+ iPhonebookStore.Read(iStatus, iSlotNum, 1, iPhonebookDataPtr);
+ SetActive();
+ LOGACTIVETIMESTAMP();
+ }
+ else
+ {
+ iSession.Server().CompleteDoSync(iStatus.Int());
+ return;
+ }
+ }
+ }
+ break;
+
+ case ESyncContactsWithICCStateRemoveUnconfirmedEntries:
+ {
+ //
+ // If we have unconfirmed entries to remove, then delete one of
+ // them before yielding to the scheduler (so we don't spend too
+ // much time in the RunL() in one go). Otherwise we have finished.
+ //
+ if (iUnconfirmedEntries.Count() > 0)
+ {
+ //
+ // Get the contact ID for the entry we are going to delete...
+ //
+ TContactItemId contactId;
+ TInt result;
+
+ result = iPhonebookManager.GetContactIdFromSlotNum(iPhonebookUid,
+ iUnconfirmedEntries[0],
+ contactId);
+ if (result != KErrNone)
+ {
+ iSession.Server().CompleteDoSync(result);
+ return;
+ }
+
+ //
+ // Delete the entry...
+ //
+ TRAP(result, iDb.DeleteContactL(contactId));
+ if (result != KErrNone)
+ {
+ iSession.Server().CompleteDoSync(result);
+ return;
+ }
+
+ //
+ // Reset the Look-Up Table entry...
+ //
+ result = iPhonebookManager.UpdateEntryInTable(iPhonebookUid,
+ iUnconfirmedEntries[0],
+ KNullContactId,
+ ESlotEmpty);
+ if (result != KErrNone)
+ {
+ iSession.Server().CompleteDoSync(result);
+ return;
+ }
+
+ //
+ // Remove this entry from the list and yield...
+ //
+ iUnconfirmedEntries.Remove(0);
+ YieldToOtherActiveObjects();
+ }
+ else
+ {
+ //
+ // Compress the database if needed and we are finished!
+ //
+ if (iDb.CompressRequired())
+ {
+ TRAP_IGNORE(iDb.CompactL());
+ }
+
+ iState = ESyncContactsWithICCStateIdle;
+
+ iSession.Server().CompleteDoSync(KErrNone);
+ }
+ }
+ break;
+
+ case ESyncContactsWithICCStateWaitForCancel:
+ {
+ iState = ESyncContactsWithICCStateIdle;
+ iSession.Server().CompleteDoSync(iStatus.Int());
+ }
+ break;
+
+ default:
+ {
+ PhBkSyncPanic(EPhBkSyncPanicDoMultipleReadError);
+ }
+ break;
+ }
+ } // CSyncContactsWithICC::RunL
+
+
+/**
+ * Simple function that causes the Active Object to yield to the scheduler
+ * and let any other Active Objects (such as the engine) run if they want.
+ */
+void CSyncContactsWithICC::YieldToOtherActiveObjects()
+ {
+ LOGACTIVE1(_L8("CSyncContactsWithICC::YieldToOtherActiveObjects()"));
+
+ //
+ // Post a dummy request...
+ //
+ iStatus = KRequestPending;
+ SetActive();
+ LOGACTIVETIMESTAMP();
+
+ //
+ // Now complete the dummy request...
+ //
+ TRequestStatus* reqStatusPtr = &iStatus;
+
+ User::RequestComplete(reqStatusPtr, KErrNone);
+ } // CSyncContactsWithICC::YieldToOtherActiveObjects
+
+
+/**
+ * Decode the phonebook entries supplied in iPhoneData. The entries are
+ * converted from TLV (Tag-Length-Value) format into the phonebook server internal
+ * (CSyncContactICCEntry) format and then written to the Contacts Database.
+ * Once they are written to the DB, the server's look-up table is updated
+ * accordingly.
+ *
+ * @param aIndex Returns the slot number of the last decoded
+ * phonebook entry.
+ * @param aReceivedEntries Returns the number of the received entries.
+ */
+void CSyncContactsWithICC::DecodeICCAndStoreToDbL(TInt& aIndex,
+ TInt& aReceivedEntries)
+ {
+ LOGACTIVE1(_L8("CSyncContactsWithICC::DecodeICCAndStoreToDbL()"));
+
+ TBuf16<KPBDataClientBuf> buffer;
+ TPtrC16 bufPtr(buffer);
+
+ TUint8 tagValue(0);
+ TInt entryCount(0);
+ CPhoneBookBuffer::TPhBkTagType dataType;
+
+ TBool isAdditionalNumber(EFalse); // Used to indicate beginning of an Additional Number
+ CSyncContactICCEntry::TSyncAdditionalNumber additionalNumber;
+
+ //
+ // Allocate an ICC Entry...
+ //
+ CSyncContactICCEntry* iccEntry = CSyncContactICCEntry::NewL();
+ CleanupStack::PushL(iccEntry);
+
+ //
+ // Create a CPhoneBookBuffer ready to decode the entries...
+ //
+ CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer();
+ CleanupStack::PushL(pbBuffer);
+ pbBuffer->Set(&iPhonebookDataPtr);
+
+ //
+ // Now start decoding the phonebook data received in TLV format...
+ //
+ pbBuffer->StartRead();
+
+ while (pbBuffer->GetTagAndType(tagValue, dataType) == KErrNone)
+ {
+ switch (tagValue)
+ {
+ case RMobilePhoneBookStore::ETagPBAdnIndex:
+ {
+ entryCount++; // Don't increment this until we find the index
+ // So that we wait for whole entry to be received
+ TUint16 index;
+ pbBuffer->GetValue(index);
+ iccEntry->iSlotNum = (TInt) index;
+ aIndex = iccEntry->iSlotNum;
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBTonNpi:
+ {
+ TUint8 tonNpi;
+
+ pbBuffer->GetValue(tonNpi);
+ if (isAdditionalNumber)
+ {
+ additionalNumber.iTON = ConvertTypeOfNumber(tonNpi); // TON associated with additional number
+
+ // We have rearched to the end of one additional number. So,
+ // we add the complete additionNumber into the list and set
+ // the flag as EFalse. Note we will get a ETagPBAnrStart for
+ // each additional number.
+ iccEntry->iNumberList->AppendL(additionalNumber);
+ isAdditionalNumber = EFalse;
+ }
+ else
+ {
+ // TON associated with first (default) number
+ iccEntry->iTON = ConvertTypeOfNumber(tonNpi);
+ }
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBText:
+ {
+ pbBuffer->GetValue(bufPtr);
+ if (isAdditionalNumber)
+ {
+ // For additional number bufPtr contains number alpha string
+ additionalNumber.iNumberString.Copy(bufPtr);
+ }
+ else
+ {
+ iccEntry->iName.Copy(bufPtr);
+ }
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBSecondName:
+ {
+ pbBuffer->GetValue(bufPtr);
+ iccEntry->iSecondName.Copy(bufPtr);
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBNumber:
+ {
+ pbBuffer->GetValue(bufPtr);
+ if (isAdditionalNumber)
+ {
+ additionalNumber.iNumber.Copy(bufPtr);
+ }
+ else
+ {
+ // First number so this will be used as default number
+ iccEntry->iNumber.Append(bufPtr);
+ }
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBAnrStart:
+ {
+ // This tag should precede every additional number entry
+ isAdditionalNumber = ETrue;
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBGroupName:
+ {
+ pbBuffer->GetValue(bufPtr);
+ iccEntry->iGroupList->AppendL(bufPtr);
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBEmailAddress:
+ {
+ pbBuffer->GetValue(bufPtr);
+ iccEntry->iEmailList->AppendL(bufPtr);
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBHiddenInfo:
+ {
+ TUint8 hidden;
+
+ pbBuffer->GetValue(hidden);
+ if (hidden != 0)
+ {
+ iccEntry->iIsHidden = ETrue;
+ }
+ }
+ break;
+
+ case RMobilePhoneBookStore::ETagPBNewEntry:
+ {
+ //
+ // This signals the end of the entry and is a special case
+ // which will be handled below.
+ //
+ }
+ break;
+
+ default:
+ {
+ //
+ // An unsupported field type - just skip this value
+ //
+ pbBuffer->SkipValue(dataType);
+ }
+ break;
+ }
+
+ //
+ // Has the whole entry been extracted?
+ //
+ if ((tagValue == RMobilePhoneBookStore::ETagPBNewEntry && entryCount > 0) ||
+ (pbBuffer->RemainingReadLength() == 0 && entryCount > 0))
+ {
+ iccEntry->iPhonebookUid = iPhonebookUid;
+
+#ifdef _DEBUG
+ iccEntry->LogSyncContactICCEntry();
+#endif
+
+ //
+ // Write the entry to the Contacts Database...
+ //
+ TContactItemId id(KNullContactId);
+ TPhonebookSlotState slotState(ESlotUsedAvailable);
+ if (iccEntry->iIsHidden)
+ // Hidden entry so ignore all fields for that entry, since they will not
+ // be stored in Contacts database
+ {
+ slotState = ESlotHiddenNotAvailable;
+ // remove any existing entry for this slot from database
+ TInt result = iPhonebookManager.GetContactIdFromSlotNum(iPhonebookUid,
+ iccEntry->iSlotNum,
+ id);
+ if (result == KErrNone)
+ {
+ iDb.DeleteContactL(id);
+ id = KNullContactId;
+ // Populate the phonebook look-up table
+ User::LeaveIfError(iPhonebookManager.UpdateEntryInTable(iPhonebookUid,
+ iccEntry->iSlotNum,
+ id, slotState));
+ }
+ }
+ else // Not hidden entry or it used to be hidden but its not anymore
+ {
+ // So add this entry to Contacts database
+
+ id = iSession.Server().WriteICCContactToDBL(*iccEntry);
+ }
+
+ // ICC entry successfully written Contacts DB, so update look-up table
+ if((id!=KNullContactId) || (iccEntry->iIsHidden))
+ {
+ // Populate the phonebook look-up table
+ User::LeaveIfError(iPhonebookManager.UpdateEntryInTable(iPhonebookUid,
+ iccEntry->iSlotNum,
+ id, slotState));
+ }
+
+ //
+ // Loop again...
+ //
+ iccEntry->Reset();
+ aReceivedEntries++;
+ }
+ }
+
+ iPhonebookDataPtr.Zero();
+
+ CleanupStack::PopAndDestroy(2, iccEntry);
+ } // CSyncContactsWithICC::DecodeICCAndStoreToDbL
+
+
+/**
+ * Converts an ETSI Type-Of-Number value to a RMobilePhone::TMobileTON.
+ *
+ * @param aValue An ETSI Type-Of-Number field.
+ *
+ * @return The equivalent RMobilePhone::TMobileTON value.
+ */
+RMobilePhone::TMobileTON CSyncContactsWithICC::ConvertTypeOfNumber(TUint8 aValue) const
+ {
+ //
+ // Mask off NPI and move TON to least-sig byte...
+ //
+ TUint8 aTon = (aValue & KEtsiTonPosition) >> 4;
+
+ //
+ // The below 'magic numbers' come from the ETSI 03.40
+ // specification for Address Fields (section 9.1.2.5)
+ //
+ RMobilePhone::TMobileTON result;
+
+ switch(aTon)
+ {
+ case 0:
+ {
+ result = RMobilePhone::EUnknownNumber;
+ }
+ break;
+
+ case 1:
+ {
+ result = RMobilePhone::EInternationalNumber;
+ }
+ break;
+
+ case 2:
+ {
+ result = RMobilePhone::ENationalNumber;
+ }
+ break;
+
+ case 3:
+ {
+ result = RMobilePhone::ENetworkSpecificNumber;
+ }
+ break;
+
+ case 4:
+ {
+ result = RMobilePhone::ESubscriberNumber;
+ }
+ break;
+
+ default:
+ {
+ result = RMobilePhone::EUnknownNumber;
+ }
+ break;
+ }
+
+ return result;
+ } // CSyncContactsWithICC::ConvertTypeOfNumber
+
+
+/**
+ * Standard Active Object DoCancel method called when the objects Cancel()
+ * method is called.
+ */
+void CSyncContactsWithICC::DoCancel()
+ {
+ if (iState == ESyncContactsWithICCStateWaitForRead)
+ {
+ iPhonebookStore.CancelAsyncRequest(EMobilePhoneBookStoreRead);
+ iState = ESyncContactsWithICCStateWaitForCancel;
+ }
+ } // CSyncContactsWithICC::DoCancel
+
+
+/**
+ * Standard Active Object RunError method called when the objects RunL()
+ * method leaves.
+ *
+ * Hopefully this method should never be called.
+ *
+ * @param aError Leave code from the RunL().
+ *
+ * @return KErrNone is returned although the server will panic first.
+ */
+TInt CSyncContactsWithICC::RunError(TInt aError)
+ {
+#ifdef _DEBUG
+ LOGACTIVE2(_L8("CSyncContactsWithICC::RunError(%d)"), aError);
+#else
+ (void) aError;
+#endif
+
+ PhBkSyncPanic(EPhBkSyncPanicUnexpectedLeave);
+
+ return KErrNone;
+ } // CSyncContactsWithICC::RunError