qtmobility/plugins/contacts/symbiansim/src/cntsimstoreprivate.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
--- a/qtmobility/plugins/contacts/symbiansim/src/cntsimstoreprivate.cpp	Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/plugins/contacts/symbiansim/src/cntsimstoreprivate.cpp	Mon May 03 13:18:40 2010 +0300
@@ -42,12 +42,14 @@
 #include "cntsimstoreprivate.h"
 #include "cntsymbiansimtransformerror.h"
 #include "cntsimstore.h"
+#include "cntsimstoreeventlistener.h"
 
 #include <mmtsy_names.h>
 #include <qtcontacts.h>
-
+#include <qcontactchangeset.h>
+#include <QDebug>
 
-const int KOneSimContactBufferSize = 512;
+const TInt KOneSimContactBufferSize = 512;
 const TInt KDataClientBuf  = 128;
 const TInt KEtsiTonPosition = 0x70;
 
@@ -66,7 +68,9 @@
      m_engine(engine),
      m_simStore(simStore),
      m_storeName(storeName),
-     m_storeInfoPckg(m_storeInfo)
+     m_readOnlyAccess(false),
+     m_storeInfoPckg(m_storeInfo),
+     m_listener(0)
 {
     CActiveScheduler::Add(this);
     m_managerUri = engine.managerUri();
@@ -77,6 +81,10 @@
     TBuf<RMobilePhoneBookStore::KMaxPBIDSize> storeName;
     convertStoreNameL(storeName);
     
+    // SDN store is always read only
+    if (m_storeName == KParameterValueSimStoreNameSdn)
+        m_readOnlyAccess = true;
+
     // Open etel server
     User::LeaveIfError(m_etelServer.Connect());
     User::LeaveIfError(m_etelServer.LoadPhoneModule(KMmTsyModuleName));
@@ -104,16 +112,19 @@
     PbkPrintToLog(_L("CntSymbianSimEngine::getEtelStoreInfoL() - MaxNumLength = %d"),
             m_storeInfo.iMaxNumLength);
     PbkPrintToLog(_L("CntSymbianSimEngine::getEtelStoreInfoL() - MaxTextLength = %d"),
-            m_storeInfo.iMaxTextLength);    
+            m_storeInfo.iMaxTextLength);
+    
+    m_listener = new (ELeave) CntSimStoreEventListener(m_engine, m_etelStore);
+    m_listener->start();
 }
 
 CntSimStorePrivate::~CntSimStorePrivate()
 {
     Cancel();
-    m_buffer.Close();
+    delete m_listener;
     m_etelStore.Close();
     m_etelPhone.Close();
-    m_etelServer.Close();    
+    m_etelServer.Close();
 }
 
 void CntSimStorePrivate::convertStoreNameL(TDes &storeName)
@@ -140,23 +151,12 @@
     }
 }
 
-QContactManager::Error CntSimStorePrivate::getInfo()
+bool CntSimStorePrivate::read(int index, int numSlots, QContactManager::Error *error)
 {
-    if (IsActive())
-        return QContactManager::LockedError;
-    
-    // start get info request
-    m_etelStore.GetInfo(iStatus, (TDes8&)m_storeInfoPckg);
-    SetActive();
-    m_state = GetInfoState;
-    
-    return QContactManager::NoError;
-}
-
-QContactManager::Error CntSimStorePrivate::read(int index, int numSlots)
-{
-    if (IsActive())
-        return QContactManager::LockedError;
+    if (IsActive()) {
+        *error = QContactManager::LockedError;
+        return false;
+    }
     
     // start reading
     m_buffer.Zero();
@@ -165,29 +165,35 @@
     SetActive();
     m_state = ReadState;
     
-    return QContactManager::NoError;
+    *error = QContactManager::NoError;
+    return true;
 }
 
-QContactManager::Error CntSimStorePrivate::write(const QContact &contact)
+bool CntSimStorePrivate::write(const QContact &contact, QContactManager::Error *error)
 {
-    if (IsActive())
-        return QContactManager::LockedError;
+    if (IsActive()) {
+        *error = QContactManager::LockedError;
+        return false;
+    }
     
     // get index
     m_writeIndex = KErrNotFound;
     if (contact.id().managerUri() == m_managerUri &&
         contact.localId() > 0) {
-        m_writeIndex = contact.localId();  
+        m_writeIndex = contact.localId();
+
+        // TODO: check that the contact exist in the sim 
     }
     
     // encode
     m_buffer.Zero();
     m_buffer.ReAlloc(KOneSimContactBufferSize);
-    TRAPD(err, m_convertedContact = encodeSimContactL(&contact, m_buffer));
+    m_convertedContact = QContact(contact);
+
+    TRAPD(err, encodeSimContactL(&m_convertedContact, m_buffer));
     if (err != KErrNone) {
-        QContactManager::Error qtError;
-        CntSymbianSimTransformError::transformError(err, qtError);
-        return qtError;
+        CntSymbianSimTransformError::transformError(err, error);
+        return false;
     }
 
     // start writing
@@ -195,13 +201,16 @@
     SetActive();
     m_state = WriteState;
     
-    return QContactManager::NoError;
+    *error = QContactManager::NoError;
+    return true;
 }
 
-QContactManager::Error CntSimStorePrivate::remove(int index)
+bool CntSimStorePrivate::remove(int index, QContactManager::Error *error)
 {
-    if (IsActive())
-        return QContactManager::LockedError;
+    if (IsActive()) {
+        *error = QContactManager::LockedError;
+        return false;
+    }
     
     // NOTE:
     // If index points to an empty slot and running in hardware the 
@@ -211,41 +220,65 @@
     SetActive();
     m_state = DeleteState;
     
-    return QContactManager::NoError;
+    *error = QContactManager::NoError;
+    return true;
+}
+
+bool CntSimStorePrivate::getReservedSlots(QContactManager::Error *error)
+{
+    if (IsActive()) {
+        *error = QContactManager::LockedError;
+        return false;
+    }
+    
+    // start reading
+    m_buffer.Zero();
+    m_buffer.ReAlloc(KOneSimContactBufferSize*m_storeInfo.iTotalEntries);
+    m_etelStore.Read(iStatus, 1, m_storeInfo.iTotalEntries, m_buffer);
+    SetActive();
+    m_state = ReadReservedSlotsState;
+    
+    *error = QContactManager::NoError;
+    return true;  
 }
 
 void CntSimStorePrivate::DoCancel()
 {
-    if (m_state == GetInfoState)
-        m_etelStore.CancelAsyncRequest(EMobilePhoneStoreGetInfo);
     if (m_state == ReadState)
         m_etelStore.CancelAsyncRequest(EMobilePhoneStoreRead);
     if (m_state == WriteState)
         m_etelStore.CancelAsyncRequest(EMobilePhoneStoreWrite);
     if (m_state == DeleteState)
         m_etelStore.CancelAsyncRequest(EMobilePhoneStoreDelete);
+    if (m_state == ReadReservedSlotsState)
+        m_etelStore.CancelAsyncRequest(EMobilePhoneStoreRead);
     
     m_state = InactiveState;
 }
 
 void CntSimStorePrivate::RunL()
 {
+    //qDebug() << "CntSimStorePrivate::RunL()" << m_state << iStatus.Int();
+    
+    m_asyncError = iStatus.Int();
     User::LeaveIfError(iStatus.Int());
     
     // NOTE: It is assumed that emitting signals is queued
     
     switch (m_state)
     {
-        case GetInfoState:
-        {
-            emit m_simStore.getInfoComplete(m_storeInfo, QContactManager::NoError);
-        }
-        break;
-        
         case ReadState:
         {
             QList<QContact> contacts = decodeSimContactsL(m_buffer);
-            m_buffer.Zero();
+
+            // set sync target
+            QList<QContact>::iterator i;
+            for (i = contacts.begin(); i != contacts.end(); ++i) {
+                QContactSyncTarget syncTarget;
+                syncTarget.setSyncTarget(KSimSyncTarget);
+                i->saveDetail(&syncTarget);
+            }
+            
             emit m_simStore.readComplete(contacts, QContactManager::NoError);
         }
         break;
@@ -259,10 +292,12 @@
             m_convertedContact.setId(contactId);  
             
             // set sync target
-            QContactSyncTarget syncTarget;
-            syncTarget.setSyncTarget(KSimSyncTarget);
-            m_convertedContact.saveDetail(&syncTarget);
-            
+            if(m_convertedContact.detail(QContactSyncTarget::DefinitionName).isEmpty()) {
+                QContactSyncTarget syncTarget = m_convertedContact.detail(QContactSyncTarget::DefinitionName);
+                syncTarget.setSyncTarget(KSimSyncTarget);
+                m_convertedContact.saveDetail(&syncTarget);
+            }
+
             emit m_simStore.writeComplete(m_convertedContact, QContactManager::NoError);
         }
         break;
@@ -273,6 +308,13 @@
         }
         break;
         
+        case ReadReservedSlotsState:
+        {
+            QList<int> reservedSlots = decodeReservedSlotsL(m_buffer);
+            emit m_simStore.getReservedSlotsComplete(reservedSlots, QContactManager::NoError);
+        }
+        break;
+        
         default:
         {
             User::Leave(KErrUnknown);
@@ -285,22 +327,19 @@
 TInt CntSimStorePrivate::RunError(TInt aError)
 {
     QContactManager::Error qtError = QContactManager::NoError;
-    CntSymbianSimTransformError::transformError(aError, qtError);
+    CntSymbianSimTransformError::transformError(aError, &qtError);
     
     // NOTE: It is assumed that emitting signals is queued
         
-    if (m_state == GetInfoState) {
-        RMobilePhoneBookStore::TMobilePhoneBookInfoV5 emptyInfo;
-        emit m_simStore.getInfoComplete(emptyInfo, qtError);
-    } else if (m_state == ReadState) {
-        QList<QContact> emptyList;
-        emit m_simStore.readComplete(emptyList, qtError);            
-    } else if (m_state == WriteState) {
+    if (m_state == ReadState) 
+        emit m_simStore.readComplete(QList<QContact>(), qtError);            
+    else if (m_state == WriteState)
         emit m_simStore.writeComplete(m_convertedContact, qtError);  
-    } else if (m_state == DeleteState) {
+     else if (m_state == DeleteState)
         emit m_simStore.removeComplete(qtError);
-    }
-    
+    else if (m_state == ReadReservedSlotsState)
+        emit m_simStore.getReservedSlotsComplete(QList<int>(), qtError);
+        
     m_state = InactiveState;
     
     return KErrNone;
@@ -368,6 +407,8 @@
                             QString number = lastNumber.number();
                             number.insert(0, "+");
                             lastNumber.setNumber(number);
+                            if (m_readOnlyAccess)
+                                m_engine.setReadOnlyAccessConstraint(&lastNumber);
                             currentContact.saveDetail(&lastNumber);
                         }
                     }
@@ -390,9 +431,11 @@
                         QContactName name;
                         QString nameString = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                         name.setCustomLabel(nameString);
+                        if (m_readOnlyAccess)
+                            m_engine.setReadOnlyAccessConstraint(&name);                        
                         currentContact.saveDetail(&name);
                         QContactManager::Error error(QContactManager::NoError);
-                        currentContact = m_engine.setContactDisplayLabel(m_engine.synthesizedDisplayLabel(currentContact, error), currentContact);
+                        m_engine.setContactDisplayLabel(&currentContact, m_engine.synthesizedDisplayLabel(currentContact, &error));
                     }
                 }
                 break;
@@ -403,6 +446,8 @@
                     QContactNickname nickName;
                     QString name = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                     nickName.setNickname(name);
+                    if (m_readOnlyAccess)
+                        m_engine.setReadOnlyAccessConstraint(&nickName);                    
                     currentContact.saveDetail(&nickName);
                 }
                 break;
@@ -411,9 +456,10 @@
             {
                 if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                     QContactPhoneNumber phoneNumber;
-                    phoneNumber.setSubTypes( QContactPhoneNumber::SubTypeMobile );
                     QString number = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                     phoneNumber.setNumber(number);
+                    if (m_readOnlyAccess)
+                        m_engine.setReadOnlyAccessConstraint(&phoneNumber);                    
                     currentContact.saveDetail(&phoneNumber);
                 }
                 break;
@@ -430,6 +476,8 @@
                     QContactEmailAddress email;
                     QString emailAddress = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                     email.setEmailAddress(emailAddress);
+                    if (m_readOnlyAccess)
+                        m_engine.setReadOnlyAccessConstraint(&email);                    
                     currentContact.saveDetail(&email);
                 }
                 break;
@@ -473,129 +521,150 @@
  *
  * \param contact QContact to be converted
  * \param rawData Contact in TLV format on return.
- * \return QContact containing actually saved information.
 */
-QContact CntSimStorePrivate::encodeSimContactL(const QContact* contact, TDes8& rawData) const
+void CntSimStorePrivate::encodeSimContactL(QContact* contact, TDes8& rawData) const
 {
-    PbkPrintToLog(_L("CntSymbianSimEngine::encodeSimContactL() - IN"));
-    QContact convertedContact;
+    // TODO: get detail definition schema and verify (unique)
+
+    // Keep track of the count of phone numbers added
+    int phoneNumberCount(0);
+    int emailCount(0);
+
     CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer();
     CleanupStack::PushL(pbBuffer);
     pbBuffer->Set(&rawData);
-
-    //add new enty tag
     User::LeaveIfError(pbBuffer->AddNewEntryTag());
 
-    //add name
-    QString name;
-    QList<QContactDetail> nameDetails = contact->details(QContactName::DefinitionName);
-    if (nameDetails.count() == 0) {
-        // TODO: should we leave name empty?
-        name.append("Unnamed");
-    }
-    else {
-        QContactName nameDetail = static_cast<QContactName>(nameDetails.at(0));
-        name.append(nameDetail.customLabel());
-        if (name.isNull()) {
-            // TODO: should we leave name empty?
-            name.append("Unnamed)");
-        }
-    }
-    name = name.left(m_storeInfo.iMaxTextLength); //trim to the max possible length
-    TPtrC nameValue(reinterpret_cast<const TUint16*>(name.utf16()));
-    User::LeaveIfError(pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText, nameValue));
+    foreach(QContactDetail detail, contact->details()) {
+        QString definitionName = detail.definitionName();
+
+        if (definitionName == QContactName::DefinitionName) {
+            // Name
+            QContactName nameDetail = static_cast<QContactName>(detail);
+            // Trim to the max possible length
+            QString name = nameDetail.customLabel().left(m_storeInfo.iMaxTextLength);
+            if (name.isEmpty()) {
+                name = "Unnamed";
+            }
+            putTagAndValueL(
+                pbBuffer,
+                RMobilePhoneBookStore::ETagPBText,
+                name);
+            // Replace detail value with the trimmed one
+            nameDetail.setCustomLabel(name);
+            contact->saveDetail(&nameDetail);
+        } else if (definitionName == QContactPhoneNumber::DefinitionName
+#ifndef SYMBIANSIM_BACKEND_PHONEBOOKINFOV1
+            && (phoneNumberCount == 0
+            || phoneNumberCount <= m_storeInfo.iMaxAdditionalNumbers)) {
+#else
+            && phoneNumberCount == 0) {
+#endif
+            // Phone number
+            phoneNumberCount++;
+            QContactPhoneNumber numberDetail = static_cast<QContactPhoneNumber>(detail);
+            QString number = numberDetail.number();
+
+            // Verify the number only contains legal digits
+            foreach (const QChar character, number) {
+                if(!character.isDigit()) {
+                    if(character != QChar('+')
+                        && character != QChar('*')
+                        && character != QChar('#')
+                        && character != QChar('p')
+                        && character != QChar('w')) {
+                        User::Leave(KErrArgument);
+                    }
+                }
+            }
+
+            // TODO: check if the number is empty (do we have a test case for that?)
 
-    QContactName convertedNameDetail;
-    convertedNameDetail.setCustomLabel(name);
-    convertedContact.saveDetail(&convertedNameDetail);
+            // Verify the number length
+            PbkPrintToLog(_L("CntSymbianSimEngine::encodeSimContactL() - phone number length = %d"),
+                numberDetail.number().length());
+            if (numberDetail.number().length() > m_storeInfo.iMaxNumLength) {
+                User::Leave(KErrTooBig);
+            }
+
+            if (phoneNumberCount > 1) {
+                // Mark the beginning of an additional number
+                User::LeaveIfError(pbBuffer->AddNewNumberTag());
+            }
 
-    //add nickname
-    if (m_storeInfo.iMaxSecondNames > 0) {
-        QString nickname;
-        QList<QContactDetail> nicknameDetails = contact->details(QContactNickname::DefinitionName);
-        if (nicknameDetails.count() > 0) {
-            QContactNickname nicknameDetail = static_cast<QContactNickname>(nicknameDetails.at(0));
-            nickname = nicknameDetail.nickname();
-            nickname = nickname.left(m_storeInfo.iMaxTextLengthSecondName); //trim to the max possible length
-            TPtrC nicknameValue(reinterpret_cast<const TUint16*>(nickname.utf16()));
-            User::LeaveIfError(pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBSecondName, nicknameValue));
-
-            QContactNickname convertedNicknameDetail;
-            convertedNicknameDetail.setNickname(nickname);
-            convertedContact.saveDetail(&convertedNicknameDetail);
+            // The number itself
+            putTagAndValueL(
+                pbBuffer,
+                RMobilePhoneBookStore::ETagPBNumber,
+                number);
+#ifndef SYMBIANSIM_BACKEND_PHONEBOOKINFOV1
+        // Phonebook info version 1 does not support nick name or e-mail
+        } else if (definitionName == QContactNickname::DefinitionName
+            && m_storeInfo.iMaxSecondNames > 0) {
+            // nickname
+            QContactNickname nicknameDetail = static_cast<QContactNickname>(detail);
+            // Trim to the max possible length;
+            QString nickname = nicknameDetail.nickname().left(m_storeInfo.iMaxTextLengthSecondName);
+            putTagAndValueL(
+                pbBuffer,
+                RMobilePhoneBookStore::ETagPBSecondName,
+                nickname);
+            // Replace detail value with the trimmed one
+            nicknameDetail.setNickname(nickname);
+            contact->saveDetail(&nicknameDetail);
+        } else if (definitionName == QContactEmailAddress::DefinitionName
+            && emailCount < m_storeInfo.iMaxEmailAddr) {
+            emailCount++;
+            QContactEmailAddress emailDetail = static_cast<QContactEmailAddress>(detail);
+            if (emailDetail.emailAddress().length() > m_storeInfo.iMaxTextLengthEmailAddr) {
+                User::Leave(KErrTooBig);
+            }
+            putTagAndValueL(
+                pbBuffer,
+                RMobilePhoneBookStore::ETagPBEmailAddress,
+                emailDetail.emailAddress());
+#endif
+        // These are ignored in the conversion
+        } else if (definitionName == QContactSyncTarget::DefinitionName
+            || definitionName == QContactDisplayLabel::DefinitionName
+            || definitionName == QContactType::DefinitionName) {
+            // Do nothing
+        } else {
+            User::Leave(KErrArgument);
         }
     }
-
-    //add phone number
-    QList<QContactDetail> phoneNumberDetails = contact->details(QContactPhoneNumber::DefinitionName);
-    if (phoneNumberDetails.count() > 0) {
-        PbkPrintToLog(_L("CntSymbianSimEngine::encodeSimContactL() - add phone number"));
-        QContactPhoneNumber phoneNumberDetail = static_cast<QContactPhoneNumber>(phoneNumberDetails.at(0));
-        QString number = phoneNumberDetail.number();
-        foreach (const QChar character, number) {
-            if(!character.isDigit()) {
-                if(character != QChar('+')
-                    && character != QChar('*')
-                    && character != QChar('#')
-                    && character != QChar('p')
-                    && character != QChar('w')) {
-                    User::Leave(KErrArgument);
-                }
-            }
-        }
-        PbkPrintToLog(_L("CntSymbianSimEngine::encodeSimContactL() - phone number length = %d"),
-            phoneNumberDetail.number().length());
-        if (phoneNumberDetail.number().length() > m_storeInfo.iMaxNumLength) {
-            User::Leave(KErrTooBig);
-        }
-        TPtrC phoneNumberValue(reinterpret_cast<const TUint16*>(phoneNumberDetail.number().utf16()));
-        PbkPrintToLog(_L("CntSymbianSimEngine::encodeSimContactL() - number = %S"), &phoneNumberValue);
-        User::LeaveIfError(pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber, phoneNumberValue));
-
-        QContactPhoneNumber convertedPhoneNumberDetail;
-        convertedPhoneNumberDetail.setNumber(phoneNumberDetail.number());
-        convertedContact.saveDetail(&convertedPhoneNumberDetail);
-    }
+    CleanupStack::PopAndDestroy(pbBuffer);
+}
 
-    //add additional numbers
-    if (m_storeInfo.iMaxAdditionalNumbers > 0) {
-        //one number is saved already
-        for (int i = 1; i < phoneNumberDetails.count() && i-1 < m_storeInfo.iMaxAdditionalNumbers; ++i) {
-            QContactPhoneNumber phoneNumberDetail = static_cast<QContactPhoneNumber>(phoneNumberDetails.at(i));
-            if (phoneNumberDetail.number().length() > m_storeInfo.iMaxNumLengthAdditionalNumber) {
-                User::Leave(KErrTooBig);
-            }
-            //mark the beginning of an additional number
-            User::LeaveIfError(pbBuffer->AddNewNumberTag());
-            //add number itself
-            TPtrC phoneNumberValue(reinterpret_cast<const TUint16*>(phoneNumberDetail.number().utf16()));
-            User::LeaveIfError(pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber, phoneNumberValue));
-
-            QContactPhoneNumber convertedPhoneNumberDetail;
-            convertedPhoneNumberDetail.setNumber(phoneNumberDetail.number());
-            convertedContact.saveDetail(&convertedPhoneNumberDetail);
-        }
-    }
-
-    //add e-mails
-    if (m_storeInfo.iMaxEmailAddr > 0) {
-        QList<QContactDetail> emailDetails = contact->details(QContactEmailAddress::DefinitionName);
-        for (int i = 0; i < emailDetails.count() && i < m_storeInfo.iMaxEmailAddr; ++i) {
-            QContactEmailAddress emailDetail = static_cast<QContactEmailAddress>(emailDetails.at(i));
-            TPtrC emailValue(reinterpret_cast<const TUint16*>(emailDetail.emailAddress().utf16()));
-            if (emailValue.Length() > m_storeInfo.iMaxTextLengthEmailAddr) {
-                User::Leave(KErrTooBig);
-            }
-            User::LeaveIfError(pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBEmailAddress, emailValue));
-
-            QContactEmailAddress convertedEmailDetail;
-            convertedEmailDetail.setEmailAddress(emailDetail.emailAddress());
-            convertedContact.saveDetail(&convertedEmailDetail);
-        }
-    }
-
-    CleanupStack::PopAndDestroy(pbBuffer);
-    PbkPrintToLog(_L("CntSymbianSimEngine::encodeSimContactL() - OUT"));
-    return convertedContact;
+void CntSimStorePrivate::putTagAndValueL(CPhoneBookBuffer* pbBuffer, TUint8 tag, QString data) const
+{
+    TPtrC value(reinterpret_cast<const TUint16*>(data.utf16()));
+    User::LeaveIfError(pbBuffer->PutTagAndValue(tag, value));
 }
 
+QList<int> CntSimStorePrivate::decodeReservedSlotsL(TDes8& rawData) const
+{
+    QList<int> reservedSlots;
+
+    TUint8 tagValue(0);
+    CPhoneBookBuffer::TPhBkTagType dataType;
+
+    CPhoneBookBuffer* pbBuffer = new (ELeave) CPhoneBookBuffer();
+    CleanupStack::PushL(pbBuffer);
+    pbBuffer->Set(&rawData);
+    pbBuffer->StartRead();
+
+    while (pbBuffer->GetTagAndType(tagValue, dataType) == KErrNone)
+    {
+        if (tagValue == RMobilePhoneBookStore::ETagPBAdnIndex) 
+        {
+            TUint16 index;
+            if (pbBuffer->GetValue(index) == KErrNone)
+                reservedSlots.append(index);
+        } else
+            pbBuffer->SkipValue(dataType);
+    } //while
+    
+    CleanupStack::PopAndDestroy(pbBuffer);
+    return reservedSlots;
+}