// ---------------------------------------------------------------------------
// CAtPhbkStoreRead::GeneratePhbkData
// other items were commented in a header
// ---------------------------------------------------------------------------
TInt CAtPhbkStoreRead::GeneratePhbkDataL()
	{
	CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer(); // used to write phonebook data
	iPhbkData.Zero();
	pbBuffer->Set(&iPhbkData); // Set it to point to the Client buffer
	pbBuffer->AddNewEntryTag();
	
	TInt ret = pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,iReadEntry.iIndex);
	if( ret!=KErrNone )
		{
		delete pbBuffer;
		return ret;
		}
	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber, iReadEntry.iNumber);
	if( ret!=KErrNone )
		{
		delete pbBuffer;
		return ret;
		}
	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi, iReadEntry.iTon);
	if(ret!=KErrNone)
		{
		delete pbBuffer;
		return ret;
		}
	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText, iReadEntry.iText);
	if(ret != KErrNone)
		{
		delete pbBuffer;
		return ret;
		}
	
	delete pbBuffer;
	return KErrNone;
	}
void CTestLtsyPhbkWrite::WriteEntryL(TInt aIndex)
	{
	TRequestStatus status;
	TBuf8<800> pbData; // Client reserved space for phonebook data
	TInt ret;
	    
	_LIT16(KTel,"123456%03d");
	_LIT16(KText,"TelNo %03d");
	TBuf16<20> text(KTel), number(KText);

	CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer(); // used to write phonebook data
	CleanupStack::PushL(pbBuffer);
	pbBuffer->Set(&pbData); // Set it to point to the Client buffer
	pbBuffer->AddNewEntryTag();
	// convert number into TLV format and append it to allocated buffer
	TInt index = aIndex;
	ret = pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBAdnIndex,(TUint16)index);
	if( ret != KErrNone )
		{
		CleanupStack::PopAndDestroy();
		SetTestStepResult(EFail);
		}
	number.Format(KTel(), index);
	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNumber, number);
//	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBNewEntry, number);
	if( ret != KErrNone )
		{
		CleanupStack::PopAndDestroy();
		SetTestStepResult(EFail);
		}
	// convert number type into TLV format and append it to allocated buffer
	TUint8 tonNpi=KTypeOfNumber; 
	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBTonNpi, tonNpi);
	if(ret!=KErrNone)
		{
		CleanupStack::PopAndDestroy();
		SetTestStepResult(EFail);
		}

	text.Format(KText(), index);
// convert text into TLV format and append it to allocated buffer
	ret=pbBuffer->PutTagAndValue(RMobilePhoneBookStore::ETagPBText, text);
	if(ret != KErrNone)
		{
		CleanupStack::PopAndDestroy();
		SetTestStepResult(EFail);
		}
	PhoneBookStore().Write(status, pbData,index);
	User::WaitForRequest(status);
	TInt r=status.Int();
	INFO_PRINTF2(_L("Write() request status = %d"),r);
	CleanupStack::PopAndDestroy();
	}
/*! Parses SIM contacts in TLV format.
 *
 * \param rawData SIM contacts in TLV format.
 * \return List of contacts.
*/
QList<QContact> CntSimStorePrivate::decodeSimContactsL(TDes8& rawData) const
{
    PbkPrintToLog(_L("CntSymbianSimEngine::decodeSimContactsL() - IN"));
    QList<QContact> fetchedContacts;
    QContact currentContact;

    TBuf16<KDataClientBuf> buffer;
    TPtrC16 bufPtr(buffer);

    TUint8 tagValue(0);
    CPhoneBookBuffer::TPhBkTagType dataType;

    bool isAdditionalNumber = false;

    CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer();
    CleanupStack::PushL(pbBuffer);
    pbBuffer->Set(&rawData);
    pbBuffer->StartRead();

    while (pbBuffer->GetTagAndType(tagValue, dataType) == KErrNone) {
        switch (tagValue)
        {
            case RMobilePhoneBookStore::ETagPBAdnIndex:
            {
                //save contact's id (SIM card index) and manager's name
                TUint16  index;
                if (pbBuffer->GetValue(index) == KErrNone) {
                    QScopedPointer<QContactId> contactId(new QContactId());
                    contactId->setLocalId(index);
                    contactId->setManagerUri(m_managerUri);
                    currentContact.setId(*contactId);
                }
                isAdditionalNumber = false;
                break;
            }
            case RMobilePhoneBookStore::ETagPBTonNpi:
            {
                // Note, that TON info can be incorporated into the phone number by Etel
                // implementation (TSY). E.g. this is the case with Nokia TSY.
                // Here general case is implemented.

                // Check number type, we are only interested if it's international or not.
                // We assume here that ETagPBTonNpi always comes after ETagPBNumber, not before.
                TUint8  tonNpi;
                if (pbBuffer->GetValue(tonNpi) == KErrNone) {
                    TUint8  intFlag = (tonNpi & KEtsiTonPosition) >> 4;
                    if (intFlag == 1) {
                        //international number format, append "+" to the last
                        //saved number
                        QList<QContactDetail> phoneNumbers = currentContact.details(
                                QContactPhoneNumber::DefinitionName);
                        if (phoneNumbers.count() > 0) {
                            QContactPhoneNumber lastNumber = static_cast<QContactPhoneNumber>(
                                phoneNumbers.at(phoneNumbers.count() - 1));
                            QString number = lastNumber.number();
                            number.insert(0, "+");
                            lastNumber.setNumber(number);
                            if (m_storeInfo.m_readOnlyAccess)
                                m_engine.setReadOnlyAccessConstraint(&lastNumber);
                            currentContact.saveDetail(&lastNumber);
                        }
                    }
                }

                // We have rearched to the end of the number,
                // invalidate additional number flag.
                isAdditionalNumber = false;
                break;
            }
            case RMobilePhoneBookStore::ETagPBText:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    if (isAdditionalNumber) {
                        // For additional number bufPtr contains number alpha string,
                        // this is ignored currently
                    }
                    else {
                        // Contact name otherwise
                        QContactName name;
                        QString nameString = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                        name.setCustomLabel(nameString);
                        if (m_storeInfo.m_readOnlyAccess)
                            m_engine.setReadOnlyAccessConstraint(&name);
                        currentContact.saveDetail(&name);
                        QContactManager::Error error(QContactManager::NoError);
                        m_engine.setContactDisplayLabel(&currentContact, m_engine.synthesizedDisplayLabel(currentContact, &error));
                    }
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBSecondName:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    QContactNickname nickName;
                    QString name = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                    nickName.setNickname(name);
                    if (m_storeInfo.m_readOnlyAccess)
                        m_engine.setReadOnlyAccessConstraint(&nickName);
                    currentContact.saveDetail(&nickName);
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBNumber:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    QContactPhoneNumber phoneNumber;
                    QString number = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                    phoneNumber.setNumber(number);
                    if (m_storeInfo.m_readOnlyAccess)
                        m_engine.setReadOnlyAccessConstraint(&phoneNumber);
                    currentContact.saveDetail(&phoneNumber);
                }
                break;
            }
            case RMobilePhoneBookStore::ETagPBAnrStart:
            {
                // This tag should precede every additional number entry
                isAdditionalNumber = true;
                break;
            }
            case RMobilePhoneBookStore::ETagPBEmailAddress:
            {
                if (pbBuffer->GetValue(bufPtr) == KErrNone) {
                    QContactEmailAddress email;
                    QString emailAddress = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length());
                    email.setEmailAddress(emailAddress);
                    if (m_storeInfo.m_readOnlyAccess)
                        m_engine.setReadOnlyAccessConstraint(&email);
                    currentContact.saveDetail(&email);
                }
                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;
            }
        } //switch

        // save contact to the array of contact to be returned if the whole entry was extracted
        if ((tagValue == RMobilePhoneBookStore::ETagPBNewEntry && currentContact.localId() > 0) ||
            (pbBuffer->RemainingReadLength() == 0 && currentContact.localId() > 0)) {
            fetchedContacts.append(currentContact);
            //clear current contact
            currentContact.clearDetails();
            QScopedPointer<QContactId> contactId(new QContactId());
            contactId->setLocalId(0);
            contactId->setManagerUri(QString());
            currentContact.setId(*contactId);
        }
    } //while