// Copyright (c) 2003-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:// BioTestUtils.h//#include "biotestutils.h"#include <e32test.h>#include <f32fsys.h>#include <s32file.h>#include <e32uid.h>#include <txtrich.h>#include <txtfmlyr.h>#include <msvids.h>#include <msvuids.h>#include <msvruids.h>#include <e32std.h>#include <e32math.h>#include <mtclbase.h>#include <mtclreg.h>#include <msvapi.h>#include <mtmuids.h>#include <smuthdr.h>#include <biouids.h>#include <biodb.h>#include <biouids.h>#include <regpsdll.h>#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS #include <tmsvsmsentry.h>#include <bifchangeobserver.h>#include <biomessageuids.h>#include "tmsvbioinfo.h"#endif#define KCharSpace ' 'EXPORT_C CBioTestUtils::~CBioTestUtils() { Reset(); delete iBioDb; }EXPORT_C CBioTestUtils* CBioTestUtils::NewL(RTest& aRTest) { CBioTestUtils* self = new (ELeave) CBioTestUtils(aRTest); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(); return self; }EXPORT_C CBioTestUtils* CBioTestUtils::NewLC(RTest& aRTest) { CBioTestUtils* self = new(ELeave) CBioTestUtils(aRTest); CleanupStack::PushL(self); self->ConstructL(); return self; }EXPORT_C CBioTestUtils* CBioTestUtils::NewL(RTest& aRTest, TInt aCreationFlags) { CBioTestUtils* self = NewLC(aRTest, aCreationFlags); CleanupStack::Pop(); return self; }EXPORT_C CBioTestUtils* CBioTestUtils::NewLC(RTest& aRTest, TInt aCreationFlags) { CBioTestUtils* self = new(ELeave) CBioTestUtils(aRTest); CleanupStack::PushL(self); self->ConstructL(aCreationFlags); return self; }void CBioTestUtils::Reset() { if(iTestParsedFieldArray) { iTestParsedFieldArray->ResetAndDestroy(); delete iTestParsedFieldArray; iTestParsedFieldArray=NULL; } if(iMessageBody) { delete iMessageBody; iMessageBody = NULL; } if(iDir) { delete iDir; iDir = NULL; } if(iRegisteredParserDll) { delete iRegisteredParserDll; iRegisteredParserDll = NULL; } if (iBioClientMtm) { delete iBioClientMtm; iBioClientMtm=NULL; } if (iBioServerMtm) { delete iBioServerMtm; iBioServerMtm = NULL; iServerEntry = NULL; } iNumFiles = 0; iFilesProcessed = 0; iMessagesCreated = 0; CMsvTestUtils::Reset(); }//// Register a Sms Mtm server DLL//EXPORT_C void CBioTestUtils::CreateBioServerMtmRegL() { CreateServerMtmRegL(KUidMsgTypeSmartMessage, _L("BIO MTM"),KBioServerMtmFileName(), KBioClientMtmFileName(), TMsvTestDllInfo(KBioUiMtmFileName,2), TMsvTestDllInfo(KBioUiMtmFileName,1), KUidMsgTypeSmartMessage, KDataComponentFileName); }CBioTestUtils::CBioTestUtils(RTest& aRTest): CMsvTestUtils(aRTest) { iBioServiceId = KMsvNullIndexEntryId; }void CBioTestUtils::ConstructL() { TInt flags=NULL; // Settings flags for the base ConstructL() function // Loading the DLLs iRTest.Next(_L("Create Data Component FileStores")); CMsvTestUtils::ConstructL(flags); iBioDb = CBIODatabase::NewL(iFs); FileSession().SetSessionPath(_L("c:\\")); }// Overloaded constructor - allows developer to decide what components to createvoid CBioTestUtils::ConstructL(TInt aCreationFlags) { iRTest.Next(_L("Initialising Data Components")); // CMsvTestUtils::ConstructL(aCreationFlags); iBioDb = CBIODatabase::NewL(iFs); FileSession().SetSessionPath(_L("c:\\")); }void CBioTestUtils::Panic(TBioTestUtilsPanic aPanic) { Panic((TInt) aPanic); }void CBioTestUtils::Panic(TInt aPanic) { User::Panic(BIOTEST_PANIC, aPanic); }EXPORT_C TMsvId CBioTestUtils::CreateBIOEntryL(TDesC& aText, TBIOMessageType aMessageType ) { // Ensure that we have a valid service ID to work with: if (iBioServiceId==0) iBioServiceId = SetBIOServiceIdL(); // First take the descriptor reference and create a new descriptor to manipulate. // Then convert '\n' to the paragraph delimiters used in proper SMS. HBufC* localBuffer = aText.AllocL(); CleanupStack::PushL(localBuffer); TPtr messDes = localBuffer->Des(); if (aMessageType != EBiovCardMessage && aMessageType != EBiovCalenderMessage) { // convert \r\n to \n since this is what is expected from SMS when not vCard data for (TInt i=0; i<messDes.Length(); i++) { if (messDes[i]==(TText)'\r' && i<messDes.Length()-1 && messDes[i+1]==(TText)'\n') messDes.Delete(i,1); } } // Create and fill a CRichText object for the jobbie: CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL(); CleanupStack::PushL(paraFormatLayer); CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(); CleanupStack::PushL(charFormatLayer); CRichText* richText = CRichText::NewL(paraFormatLayer,charFormatLayer); CleanupStack::PushL(richText); TInt pos = richText->DocumentLength(); // Ought to be 0. richText->InsertL(pos, messDes); TMsvEntry newBioEntry; newBioEntry.SetNew(ETrue); newBioEntry.SetComplete(EFalse); newBioEntry.SetUnread(ETrue); newBioEntry.SetVisible(ETrue); newBioEntry.SetReadOnly(EFalse); newBioEntry.SetFailed(EFalse); newBioEntry.SetOperation(EFalse); newBioEntry.SetMultipleRecipients(EFalse); newBioEntry.SetAttachment(EFalse); newBioEntry.iMtm= KUidBIOMessageTypeMtm; newBioEntry.iType=KUidMsvMessageEntry; newBioEntry.iServiceId=iBioServiceId; TTime now; now.UniversalTime(); newBioEntry.iDate = now; newBioEntry.iDescription.Set(richText->Read(0, richText->DocumentLength())); TBufC<KTelephoneNumberMaxLength> telNumber; HBufC* tempNumber = CreateDummyPhoneNumberL(); telNumber = tempNumber->Des(); newBioEntry.iDetails.Set(telNumber); // Finished with telNumber, so free up the memory: delete tempNumber; // Change the iServiceId, iMtm, iBioType for message: SetForMtmTypeL(newBioEntry, aMessageType); // Update the size to that of the attachment length - correct? // Otherwise just get 68 newBioEntry.iSize = richText->DocumentLength();// msgSize; iClientServer == EServerSide ? CreateBioEntryServerSideL(newBioEntry,*richText) : CreateBioEntryClientSideL(newBioEntry,*richText); CleanupStack::PopAndDestroy(4); // richText, charFormatLayer, paraFormatLayer, localBuffer return newBioEntry.Id(); }void CBioTestUtils::SetForMtmTypeL(TMsvEntry& aEntry, TBIOMessageType aType) { TInt index; // Should have a match for the Message Type as the message is created with the SMS id's. switch(aType) { case ENoMessage: // Just to keep compiler happy! break; case EBioIapSettingsMessage: aEntry.iBioType = KUidBIOInternetAccessPointMsg; break; case EBioEnpMessage: aEntry.iBioType =KUidBIOEmailNotificationMsg; break; case EBioRingTonesMessage: aEntry.iBioType =KUidBIORingingTonesMsg; break; case EBioOpLogoMessage: aEntry.iBioType =KUidBIOOperatorLogoMsg; break; case EBioCompBusCardMessage: aEntry.iBioType =KUidBIOBusinessCardMsg; break; case EBiovCardMessage: aEntry.iBioType =KUidBIOVCardMsg; break; case EBiovCalenderMessage: aEntry.iBioType =KUidBIOVCalenderMsg; break; case EBioWAPSettingsMessage: aEntry.iBioType =KUidBIOWAPAccessPointMsg; break; case EBioWPRVSettingsMessage: aEntry.iBioType =KUidBIOWPRVMsg; break; } // Set other TMsvEntry fields if we have a BIO message type if (aType != ENoMessage) { aEntry.SetMtmData2(0); aEntry.SetMtmData3(0); } // set description from BIF file iBioDb->GetBioIndexWithMsgIDL(TUid::Uid(aEntry.iBioType),index); if(index==KErrNotFound) User::Leave(KErrNotFound); aEntry.iDescription.Set(iBioDb->BifReader(index).Description()); }EXPORT_C void CBioTestUtils::LogCurrentMessageTypeL(TMsvId aMsvId) { // assume we're already pointing at a BIO message TMsvEntry entry; TMsvId oldId; if(iClientServer == EServerSide) { oldId = iServerEntry->Entry().Id(); User::LeaveIfError(iServerEntry->SetEntry(aMsvId)); entry = iServerEntry->Entry(); } else { oldId = iMsvEntry->Entry().Id(); iMsvEntry->SetEntryL(aMsvId); entry = iMsvEntry->Entry(); } TInt biotype = entry.iBioType; if(biotype == KUidBIOInternetAccessPointMsg) { switch(entry.MtmData1()) { case 1: WriteComment(_L("IACP basic IAP message")); break; case 2: WriteComment(_L("IACP basic mail message")); break; case 3: WriteComment(_L("IACP basic IAP & mail message")); break; case 7: WriteComment(_L("IACP Internet script message")); break; case 8: WriteComment(_L("IACP SMS settings message")); break; case 15: WriteComment(_L("Telephone settings message")); break; default: WriteComment(_L("Unsupported IACP type")); break; } } else if(biotype == KUidBIOEmailNotificationMsg) WriteComment(_L("Email notification message")); else if(biotype == KUidBIORingingTonesMsg) WriteComment(_L("Ringing tones message")); else if(biotype == KUidBIOOperatorLogoMsg) WriteComment(_L("Operator logo message")); else if(biotype == KUidBIOBusinessCardMsg) WriteComment(_L("Compact Business Card message")); else if(biotype == KUidBIOVCardMsg) WriteComment(_L("vCard message")); else if(biotype == KUidBIOVCalenderMsg) WriteComment(_L("vCalendar")); else if(biotype == KUidBIOWAPAccessPointMsg) WriteComment(_L("WAP settings message")); else WriteComment(_L("Unknown type")); if(iClientServer == EServerSide) { User::LeaveIfError(iServerEntry->SetEntry(oldId)); } else { iMsvEntry->SetEntryL(oldId); } }EXPORT_C TMsvId CBioTestUtils::CreateBIOEntryFromFileL(const TDesC& aFilename, TBIOMessageType aMessageType) { //First use the filename to get the message body, // then convert '\n' to the paragraph delimiters used in proper SMS HBufC* tempBuffer; TMsvId newEntryId; tempBuffer = ReadFromFileL(aFilename); CleanupStack::PushL(tempBuffer); newEntryId = CreateBIOEntryL(*tempBuffer, aMessageType ); // Finished with our local descriptors - free up some memory CleanupStack::PopAndDestroy(); return newEntryId; }EXPORT_C void CBioTestUtils::EmptyInboxMessagesL() { // Function gets the Inbox Entry, and then all the children of this entry. // Then we iterate through the selection deleting each entry. CMsvEntrySelection* inboxMessageSel; if(iClientServer == EServerSide) { inboxMessageSel = new (ELeave) CMsvEntrySelection; CleanupStack::PushL(inboxMessageSel); // Create a local Server entry, and get the children of the Global Inbox: User::LeaveIfError(iServerEntry->SetEntry(KMsvGlobalInBoxIndexEntryId)); iServerEntry->GetChildren(*inboxMessageSel ); // children of parent, ie global inbox if (inboxMessageSel->Count() != 0) { iServerEntry->DeleteEntries(*inboxMessageSel); } // Point back at something safe before we return: User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); } else { iMsvEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId); inboxMessageSel = iMsvEntry->ChildrenL(); CleanupStack::PushL(inboxMessageSel); if (inboxMessageSel->Count() != 0) { TInt count; TMsvId currentMsgId; for (count = 0; count < inboxMessageSel->Count(); count++) { currentMsgId= inboxMessageSel->At(count); // Delete this entry DeleteLocalEntrySynchronouslyL(*iMsvEntry, currentMsgId); } } iMsvEntry->SetEntryL(KMsvRootIndexEntryId); } CleanupStack::PopAndDestroy(); // inboxMessageSel }void CBioTestUtils::DeleteLocalEntrySynchronouslyL(CMsvEntry& aParentEntry, TMsvId anId) { // Creates an entry synchronously by handling the asynchrous parts locally const TMsvSelectionOrdering& originalSort=aParentEntry.SortType(); TMsvSelectionOrdering sort(originalSort); sort.SetShowInvisibleEntries(ETrue); aParentEntry.SetSortTypeL(sort); CMsvOperationWait* myDog=CMsvOperationWait::NewLC(); CMsvOperation* op=aParentEntry.DeleteL(anId, myDog->iStatus); myDog->Start(); CActiveScheduler::Start(); const TInt err=op->iStatus.Int(); TMsvLocalOperationProgress progress=McliUtils::GetLocalProgressL(*op); delete op; User::LeaveIfError(err); User::LeaveIfError(progress.iError); CleanupStack::PopAndDestroy(); aParentEntry.SetSortTypeL(originalSort); }//*************************************************************************//// Getting BIO service ID////*************************************************************************// Get,or create, the default BIO service:EXPORT_C TMsvId CBioTestUtils::SetBIOServiceIdL() { // If Bio service Id is none zero its already been set - just return the value: if (iBioServiceId) return iBioServiceId; if(iClientServer == EServerSide) SetBioServiceServerSideL(); else SetBioServiceClientSideL(); return iBioServiceId; }void CBioTestUtils::SetBioServiceServerSideL() { // Set up the RootEntry sort order first: TMsvSelectionOrdering oldSortType = iServerEntry->Sort(); TMsvSelectionOrdering sortType(KMsvGroupByType, EMsvSortByNone, ETrue); iServerEntry->SetSort(sortType); // Search the root folder for any entries which are BIO Message services. // If none are found then create one. TMsvId localServiceId=KMsvNullIndexEntryId; localServiceId = DefaultServiceForMTML(KUidBIOMessageTypeMtm, ETrue); // Check that the Service id is valid, i.e. set iCurrentEntry context to service entry: TRAPD( error, iServerEntry->SetEntry(localServiceId) ); if ( (localServiceId == KMsvUnknownServiceIndexEntryId) || (error == KErrNotFound) ) { // Id isn't a valid BIO service, so try and get the first BIO service: CMsvEntrySelection* sel = GetListOfAccountsWithMTMServerL(KUidBIOMessageTypeMtm); CleanupStack::PushL(sel); if (sel->Count()) iBioServiceId=(*sel)[0]; // Select the first available service. CleanupStack::PopAndDestroy(); // sel if (localServiceId == KMsvUnknownServiceIndexEntryId || localServiceId == KMsvNullIndexEntryId) // Haven't found any valid BIO service, so try and create a BIO service: localServiceId=CreateDefaultBIOServiceL(); } else User::LeaveIfError(error); // An error other than no service occurred. __ASSERT_DEBUG( localServiceId != KMsvNullIndexEntryId, User::Panic(_L("BioGen"), KErrNotFound)); // Point back at something safe: User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); iServerEntry->SetSort(oldSortType); iBioServiceId = localServiceId; }void CBioTestUtils::SetBioServiceClientSideL() { iMsvEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvGroupByType, EMsvSortByNone, ETrue));#if defined (_DEBUG) if (iMsvEntry->EntryId() != KMsvRootIndexEntryId) //iMsvEntry should be set to root User::Leave(KErrNotFound); //replaces a panic - ENotAServiceEntry#endif TMsvId localServiceId=KMsvNullIndexEntryId; localServiceId=DefaultServiceForMTML(KUidBIOMessageTypeMtm, ETrue); //Check if there is a valid entry for this ID TRAPD(ret, /*const TMsvEntry& ent=*/iMsvEntry->ChildDataL(localServiceId)); if (localServiceId == KMsvUnknownServiceIndexEntryId || ret==KErrNotFound) { // Our Id isn't a valid BIO service, possibly because there isn't a default // BIO service. So try and get the first BIO service. CMsvEntrySelection* sel=GetListOfAccountsWithMTMClientL(KUidBIOMessageTypeMtm); if (sel->Count()) localServiceId=(*sel)[0]; // select the first available service delete sel; if (localServiceId == KMsvUnknownServiceIndexEntryId || localServiceId == KMsvNullIndexEntryId) // No SMS service present, so let's create one CreateServicesL(); } else User::LeaveIfError(ret); // an error other than no service occurred#if defined (_DEBUG) if (localServiceId == KMsvNullIndexEntryId) User::Leave(KErrNotFound); //replaces a panic - ENotAServiceEntry#endif iBioServiceId = localServiceId; }TMsvId CBioTestUtils::CreateDefaultBIOServiceL() { // Haven't found an entry so create a BIO Message service: TMsvEntry bioServiceEntry; bioServiceEntry.iMtm = KUidBIOMessageTypeMtm; bioServiceEntry.iType = KUidMsvServiceEntry; bioServiceEntry.SetVisible(EFalse); bioServiceEntry.iDate.UniversalTime(); bioServiceEntry.iDescription.Set(_L("BIO Message Service ")); // Is there such a thing? bioServiceEntry.iDetails.Set(_L("BIO Message Service"));// no need to set default service for v2, CBaseMtm 'knows' that for services // where there is a single service entry, it has to be the default TMsvId newBIOServiceId; if(iClientServer == EServerSide) { User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); User::LeaveIfError(iServerEntry->CreateEntry(bioServiceEntry)); // Needs to be a child of the root! newBIOServiceId =bioServiceEntry.Id(); } else { iMsvEntry->SetEntryL(KMsvRootIndexEntryId); iMsvEntry->CreateL(bioServiceEntry); // Needs to be a child of the root! newBIOServiceId =bioServiceEntry.Id(); } // No need to set Server Entry - still pointing at the root. return newBIOServiceId; }TMsvId CBioTestUtils::DefaultServiceForMTML(TUid aMtmUid, TBool aFindFirstServiceIfNoDefault) { TMsvId serviceId=KMsvUnknownServiceIndexEntryId; if(iClientServer == EServerSide) serviceId = DefaultServiceServerL(aMtmUid,aFindFirstServiceIfNoDefault); else serviceId = DefaultServiceClientL(aMtmUid,aFindFirstServiceIfNoDefault); return serviceId; }TMsvId CBioTestUtils::DefaultServiceServerL(TUid aMtmUid, TBool /*aFindFirstServiceIfNoDefault*/) { TMsvId serviceId=KMsvUnknownServiceIndexEntryId; User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); // Find first available service with the desired iMtm value: CMsvEntrySelection* sel=new (ELeave) CMsvEntrySelection; CleanupStack::PushL(sel); iServerEntry->GetChildren(*sel); for (TInt count = 0; serviceId != 0 && count < sel->Count(); count++) { User::LeaveIfError(iServerEntry->SetEntry(sel->At(count))); if (iServerEntry->Entry().iMtm == aMtmUid) serviceId = sel->At(count); } CleanupStack::PopAndDestroy(); // sel // Point back at something safe: User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); return serviceId; }TMsvId CBioTestUtils::DefaultServiceClientL(TUid /*aMtmUid*/, TBool /*aFindFirstServiceIfNoDefault*/) { if (!iBioClientMtm) { InstantiateClientMtmsL(); } return iBioClientMtm->DefaultServiceL(); }CMsvEntrySelection* CBioTestUtils::GetListOfAccountsWithMTMServerL(TUid aMtmUid) { // Gets a list of entries with the passed in MTM. CMsvEntrySelection* returnSelection =new(ELeave) CMsvEntrySelection(); CleanupStack::PushL(returnSelection); CMsvEntrySelection* rootKin = new (ELeave) CMsvEntrySelection(); CleanupStack::PushL(rootKin); CMsvEntrySelection* entryKin = new (ELeave) CMsvEntrySelection(); CleanupStack::PushL(entryKin); TMsvSelectionOrdering oldSortType = iServerEntry->Sort(); TMsvSelectionOrdering sortType(KMsvGroupByType|KMsvGroupByStandardFolders, EMsvSortByDetailsReverse, ETrue); // iCurrentEntry should be pointing towards the root, but make sure: User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryIdValue)); iServerEntry->SetSort(sortType); iServerEntry->GetChildren(*rootKin); // Get the child entries of the root. TBool visible=EFalse; TInt err; if ( rootKin->Count() !=0) { TMsvEntry tentry; for (TInt cc=rootKin->Count(); --cc>=0; ) // N.B. decrements prior to entering loop. { // Set the context of our Server Entry to the next child entry of the root: User::LeaveIfError(iServerEntry->SetEntry(rootKin->At(cc)) ); // Get the entry and check its mtm type: tentry =iServerEntry->Entry(); if (tentry.iMtm==aMtmUid) { // Is it a proper service entry? if (tentry.iType.iUid==KUidMsvServiceEntryValue && tentry.Id()!=KMsvLocalServiceIndexEntryIdValue) { // If it's visible or it has no entry in the index - add to our return array: if (tentry.Visible() || tentry.iRelatedId==KMsvNullIndexEntryId) returnSelection->AppendL(tentry.Id()); else if (tentry.iRelatedId!=tentry.Id()) { // Check if there are any related entries: TRAP(err, iServerEntry->GetChildren(*entryKin) ); TInt count = entryKin->Count(); while (count--) { User::LeaveIfError(iServerEntry->SetEntry( entryKin->At(count) ) ); if (iServerEntry->Entry().Id() == tentry.iRelatedId) break; } visible=iServerEntry->Entry().Visible(); if (err==KErrNone && !visible && returnSelection->Find(tentry.iRelatedId)!=KErrNone) returnSelection->AppendL(tentry.Id()); } } } } } // Point back at something safe: User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); iServerEntry->SetSort(oldSortType); CleanupStack::PopAndDestroy(2); // entryKin, rootKin, CleanupStack::Pop(); // returnSelection return returnSelection; }CMsvEntrySelection* CBioTestUtils::GetListOfAccountsWithMTMClientL(TUid aMtmUid) { // Gets a list of entries with the passed in MTM CMsvEntrySelection* returnSelection =new(ELeave) CMsvEntrySelection(); CleanupStack::PushL(returnSelection); CMsvEntrySelection* rootKin; CMsvEntrySelection* entryKin; TMsvSelectionOrdering oldSortType = iMsvEntry->SortType(); TMsvSelectionOrdering sortType(KMsvGroupByType|KMsvGroupByStandardFolders, EMsvSortByDetailsReverse, ETrue); // iCurrentEntry should be pointing towards the root, but make sure iMsvEntry->SetEntryL(KMsvRootIndexEntryIdValue); iMsvEntry->SetSortTypeL(sortType); rootKin=iMsvEntry->ChildrenL(); // Get the child entries of the root CleanupStack::PushL(rootKin); TBool visible=EFalse; if ( rootKin->Count() !=0) { TMsvEntry tentry; for (TInt cc=rootKin->Count(); --cc>=0; ) // NB decrements prior to entering loop { // Set the context of our Server Entry to the next child entry of the root iMsvEntry->SetEntryL(rootKin->At(cc)) ; // get the entry and check it's mtm type tentry =iMsvEntry->Entry(); if (tentry.iMtm==aMtmUid) { // Is it a proper service entry if (tentry.iType.iUid==KUidMsvServiceEntryValue && tentry.Id()!=KMsvLocalServiceIndexEntryIdValue) { // if it's visible or it has no entry in the index - add to our return array if (tentry.Visible() || tentry.iRelatedId==KMsvNullIndexEntryId) returnSelection->AppendL(tentry.Id()); else if (tentry.iRelatedId!=tentry.Id()) { // Check if there are any related entries entryKin=iMsvEntry->ChildrenL() ; CleanupStack::PushL(entryKin); TInt count = entryKin->Count(); while (count--) { iMsvEntry->SetEntryL( entryKin->At(count) ); if (iMsvEntry->Entry().Id() == tentry.iRelatedId) break; } visible=iMsvEntry->Entry().Visible(); if (!visible && returnSelection->Find(tentry.iRelatedId)!=KErrNone) returnSelection->AppendL(tentry.Id()); CleanupStack::PopAndDestroy(); // entryKin } } } } } // Point back at something safe..... iMsvEntry->SetEntryL(KMsvRootIndexEntryId); iMsvEntry->SetSortTypeL(oldSortType); CleanupStack::PopAndDestroy(); // entryKin, rootKin, CleanupStack::Pop(); //returnSelection return returnSelection; }//*****************************************************************************//// File Read and Message Creation functions////*****************************************************************************EXPORT_C void CBioTestUtils::SetSessionPath(const TDesC& aSessionPath) { iFs.SetSessionPath(aSessionPath); }HBufC* CBioTestUtils::ReadFromFileL(const TDesC& aFile) { // Reads in data from a file and loads it into a buffer which is later used // to create an SMS message in the Inbox. This function differs from the others // in that it also gets any From: field by locating the token in the file. // NOTE: There is an inherent assumption that the From: token and the field will // be on a single line in the text file (i.e. less than 1024 characters. RFile file; TBuf8<1024> lineBuffer; // Buffer for Read function. TInt err=KErrNone; err = file.Open(iFs,aFile,EFileStreamText|EFileRead|EFileShareAny); if(err != KErrNone) // Didn't find the file, so leave - should only get valid filenames! { User::Leave(KErrNotFound); } // In real life this is set by the Socket Port Observer, or the SMS server. // So,in this test code we must do it by creating a random telephone number. // iMessageDetails = CreateDummyPhoneNumberL(); HBufC* bioBuf=HBufC::NewLC(65535); // Create a new descriptor on the heap. HBufC* copyBuffer=HBufC::NewLC(1024); do // Read in the text from file, and also check if there is a name field: { err = file.Read(lineBuffer);// Read upto 256 chars, '\n' and all... //err = ReadLineL(file,lineBuffer); if (err==KErrNone) // Made a valid read, if (lineBuffer.Length()==0) // but read 0 chars err=KErrEof; // so set err value to end processing if(err == KErrNone) { copyBuffer->Des().Copy(lineBuffer);// Copy, and overwrite existing text if( (bioBuf->Length() + copyBuffer->Length()) > bioBuf->Des().MaxLength() ) { bioBuf = bioBuf->ReAllocL(bioBuf->Length() + copyBuffer->Length()); } bioBuf->Des().Append(*copyBuffer); //bioBuf->Des().Append(_L("\n")); } } while(err != KErrEof); CleanupStack::PopAndDestroy(); // Destroy the copyBuffer. CleanupStack::Pop();// Remove the bioBuf. file.Close(); return bioBuf; // Transfer ownership and responsibility of the buffer. }//*****************************************************************************//// Creating a dummy phone number for use in messages////*****************************************************************************HBufC* CBioTestUtils::CreateDummyPhoneNumberL() { HBufC* number= HBufC::NewL(32); // Note: function doesn't own this, up to the caller to delete TInt64 phoneNo; TInt64 seed; TTime tempTime; tempTime.UniversalTime(); seed=tempTime.Int64(); phoneNo= Math::Rand(seed); if (phoneNo <0) phoneNo = -phoneNo; number->Des().Num( phoneNo); number->Des().Insert(0,_L("+44"));// Add a leading '+' to make if an international numbers return number; }void CBioTestUtils::CreateBioEntryServerSideL(TMsvEntry& aEntry, CRichText& aBody) { // Get the global inbox: User::LeaveIfError(iServerEntry->SetEntry(KMsvGlobalInBoxIndexEntryId)); // Entry Context already set, create our entry: User::LeaveIfError(iServerEntry->CreateEntry(aEntry)); // Set our context to the the new entry so we can create a store: User::LeaveIfError(iServerEntry->SetEntry(aEntry.Id()) ); // Save all the changes: CMsvStore* store; store=iServerEntry->EditStoreL(); CleanupStack::PushL(store); if (store->HasBodyTextL()) { store->DeleteBodyTextL(); } store->StoreBodyTextL(aBody); store->CommitL(); CleanupStack::PopAndDestroy(); // Close and destroy the store. // Set context to the new entry to allow updating of the entry: aEntry.SetComplete(ETrue); iServerEntry->ChangeEntry(aEntry); User::LeaveIfError(iServerEntry->SetEntry(KMsvRootIndexEntryId)); }void CBioTestUtils::CreateBioEntryClientSideL(TMsvEntry& aEntry, CRichText& aBody) { // Get the global inbox. iMsvEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId); iMsvEntry->CreateL(aEntry); iMsvEntry->SetEntryL(aEntry.Id()); // Save all the changes CMsvStore* store; store=iMsvEntry->EditStoreL(); CleanupStack::PushL(store); if (store->HasBodyTextL()) { store->DeleteBodyTextL(); } store->StoreBodyTextL(aBody); store->CommitL(); CleanupStack::PopAndDestroy(); //store - close the store aEntry.SetComplete(ETrue); // Update the entry iMsvEntry->ChangeL(aEntry); iMsvEntry->SetEntryL(KMsvRootIndexEntryId); }void CBioTestUtils::InstantiateClientMtmsL() { // client side __ASSERT_ALWAYS(iMsvSession, User::Panic(BIOTEST_PANIC, KErrBIONotOnClientSide)); if(iClientMtmRegistry) delete iClientMtmRegistry; iClientMtmRegistry = CClientMtmRegistry::NewL(*iMsvSession); iBioClientMtm = (CBIOClientMtm*) iClientMtmRegistry->NewMtmL(KUidMsgTypeSmartMessage); }void CBioTestUtils::InstantiateServerMtmsL() { iBioServerMtm = (CBIOServerMtm*) InstantiateServerMtmL(KUidBIOMessageTypeMtm, iBioServiceId); const CMsvEntrySelection* selection = new(ELeave)CMsvEntrySelection(); TRequestStatus st; TMsvId s =0; TRAP_IGNORE(iBioServerMtm->CopyFromLocalL(*selection,s, st)); TRAP_IGNORE(iBioServerMtm->CopyToLocalL(*selection,s, st)); TRAP_IGNORE(iBioServerMtm->CopyWithinServiceL(*selection,s, st)); TRAP_IGNORE(iBioServerMtm->MoveFromLocalL(*selection,s, st)); TRAP_IGNORE(iBioServerMtm->MoveToLocalL(*selection,s, st)); TRAP_IGNORE(iBioServerMtm->MoveWithinServiceL(*selection,s, st)); TRAP_IGNORE(iBioServerMtm->DeleteAllL(*selection,st)); TInt intw =0; TRAP_IGNORE(iBioServerMtm->Cancel()); iBioServerMtm->CommandExpected(); TMsvEntry entry; TRAP_IGNORE(iBioServerMtm->ChangeL(entry,st)); TRAP_IGNORE(iBioServerMtm->CreateL(entry,st)); delete selection; }void CBioTestUtils::DeleteServicesL() { DeleteServiceL(KUidBIOMessageTypeMtm); }void CBioTestUtils::CreateServicesL() { iBioServiceId = CreateServiceL(KUidMsgTypeSmartMessage); }void CBioTestUtils::FindExistingServicesL() { iBioServiceId = 0; TRAPD(err,ServiceIdL(KUidMsgTypeSmartMessage, iBioServiceId)); if (err) Printf(_L("No existing SMS services found!\n")); }void CBioTestUtils::InstallMtmGroupsL() { InstallMtmGroupL(KDataComponentFileName); }void CBioTestUtils::CreateServerMtmRegsL() { CreateBioServerMtmRegL(); }//// stuff to generate test BIO messages//EXPORT_C CMsvEntrySelection* CBioTestUtils::GenerateMessagesL() { return GenerateMessagesL(KBIOTxtFilePath); }EXPORT_C CMsvEntrySelection* CBioTestUtils::GenerateMessagesL(const TDesC& aFileDirectory, TBool aLogCreationDetails) { TBufC<KMaxFileName> currentFile; TMsvId messageId; TBIOMessageType currentMsgType; CMsvEntrySelection* selection = new(ELeave)CMsvEntrySelection(); CleanupStack::PushL(selection); TInt err = iFs.GetDir(aFileDirectory, KEntryAttMatchMask, ESortByName, iDir); if (err == KErrPathNotFound) { TInt makeDirErr = iFs.MkDirAll(aFileDirectory); makeDirErr==KErrNone ? User::Leave(KErrNotFound): User::Leave(makeDirErr); } else if (err!=KErrNone) { User::Leave(err); } // Set the session path for the RFs SetSessionPath(aFileDirectory); if (iDir) delete iDir; User::LeaveIfError(iFs.GetDir(_L("*.txt"), KEntryAttNormal, ESortByName, iDir)); TInt count = iDir->Count(); if(count == 0) { User::Leave(KErrNotFound); // No files to process } TBuf<60> outputBuf; for(TInt loop = 0; loop < count; loop++) { currentFile=( (*iDir)[iFilesProcessed].iName ); // Not processed all the messages - so keep the current state iFilesProcessed++; // Here because need to update the counter promptly currentMsgType = SetMessageType(currentFile); if (currentMsgType!=ENoMessage) // skip any dodgy filenames { messageId = CreateBIOEntryFromFileL( currentFile,currentMsgType); selection->AppendL(messageId); TPtrC tempPtr = (currentFile.Des() ); if (aLogCreationDetails) { outputBuf.Format(_L("TMsvId %d - %S"), messageId, &tempPtr); WriteComment(outputBuf); } } } CleanupStack::Pop(); // selection return selection; }EXPORT_C TBIOMessageType CBioTestUtils::SetMessageType(const TDesC& aFileName) { // Check each file prefix in turn with the filename passed as a parameter. // If cannot find the correct type set to ENoMessage to indicate an error. // GenerateNextMessage will then skip the file! if (aFileName.MatchF(KBIOIapPrefix)==0) // File starts with "iap" { return EBioIapSettingsMessage; } if(aFileName.MatchF(KBIOEnpPrefix)==0) // File name starts "enp" { return EBioEnpMessage; } if (aFileName.MatchF(KBIORingTonePrefix)==0)//Filename begins "rtone" { return EBioRingTonesMessage; } if (aFileName.MatchF(KBIOOpLogoPrefix)==0) // Filename begins "oplogo" { return EBioOpLogoMessage; } if (aFileName.MatchF(KBIOcBusinessCardPrefix)==0)// Filename begins "cbc" { return EBioCompBusCardMessage; } if (aFileName.MatchF(KBIOvCardPrefix)==0) { return EBiovCardMessage; } if (aFileName.MatchF(KBIOvCalenderPrefix)==0) { return EBiovCalenderMessage; } if (aFileName.MatchF(KBIOWappPrefix)==0) { return EBioWAPSettingsMessage; } // if we've reached this point it's an unknown filename return ENoMessage; }EXPORT_C void CBioTestUtils::DoAppendVariantName(TDes& aFileName) {#if defined(__WINS__) && defined(__WINSCW__) aFileName.Append(_L(".WINSCW."));#elif(__WINS__) aFileName.Append(_L(".WINS."));#endif#if (defined(__THUMB__) || defined(__MARM_THUMB__)) aFileName.Append(_L(".THUMB."));#endif#if (defined(__ARMI__) || defined(__MARM_ARMI__)) aFileName.Append(_L(".ARMI."));#endif#if (defined(__ARM4__) || defined(__MISA__) || defined(__MARM_ARM4__)) aFileName.Append(_L(".ARM4."));#endif#if defined(_DEBUG) aFileName.Append(_L("DEB."));#else aFileName.Append(_L("REL."));#endif aFileName.Append(_L("LOG")); }//// Create a return the appropriate parser for the biomsg with id //EXPORT_C CBaseScriptParser2* CBioTestUtils::CreateParserL(TMsvId aBioMsgId) { TMsvEntry myBioEntry; if(iClientServer==EClientSide) { iMsvEntry->SetEntryL(aBioMsgId); myBioEntry = iMsvEntry->Entry(); } else { User::Leave(KErrNotSupported); } // check its the right type if(myBioEntry.iMtm.iUid != KUidMsgTypeSmartMessage.iUid) User::Leave(KBspInvalidMessage); return CreateParserTypeL(myBioEntry.iBioType); }EXPORT_C CBaseScriptParser2* CBioTestUtils::CreateParserTypeL(TInt32 aBioMsgType) { // get the bio type and create the parser TUid messageUid = TUid::Uid(aBioMsgType); // look up identification for parser TFileName parserDllName(iBioDb->GetBioParserNameL(messageUid)); if (iRegisteredParserDll) // Already have an old RegParserDll, delete it to stop memory leak. { delete iRegisteredParserDll; iRegisteredParserDll = NULL; } iRegisteredParserDll = CRegisteredParserDll::NewL(parserDllName); // Create a new RegParserDll RLibrary parserlibrary; User::LeaveIfError(iRegisteredParserDll->GetLibrary(iFs, parserlibrary)); typedef CBaseScriptParser2* (*NewParserL)(CRegisteredParserDll& aRegisteredParserDll, CMsvEntry& aEntry, RFs& aFs); TInt entrypointordinalnumber=1; // The one and only entry point TLibraryFunction libFunc=parserlibrary.Lookup(entrypointordinalnumber); if (libFunc==NULL) User::Leave(KErrBadLibraryEntryPoint); NewParserL pFunc=(NewParserL) libFunc; TInt refcount=iRegisteredParserDll->DllRefCount(); CBaseScriptParser2* parser=NULL; TRAPD(ret,parser=((*pFunc)(*iRegisteredParserDll, *iMsvEntry, iFs))); if ((ret!=KErrNone) && (iRegisteredParserDll->DllRefCount()==refcount)) iRegisteredParserDll->ReleaseLibrary(); User::LeaveIfError(ret); return parser; }EXPORT_C TPtrC CBioTestUtils::MessageBodyL(TMsvId aBioMsgId) { CMsvStore* store = NULL; if(iClientServer==EServerSide) { User::LeaveIfError(iServerEntry->SetEntry(aBioMsgId)); if(iServerEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) User::Leave(KBspInvalidMessage); store = iServerEntry->ReadStoreL(); } else { iMsvEntry->SetEntryL(aBioMsgId); if(iMsvEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) User::Leave(KBspInvalidMessage); store = iMsvEntry->ReadStoreL(); } // Extract the body text or leave false if not CleanupStack::PushL(store); CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL(); CleanupStack::PushL(paraFormatLayer); CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(); CleanupStack::PushL(charFormatLayer); CRichText* richText = CRichText::NewL(paraFormatLayer, charFormatLayer); CleanupStack::PushL(richText); store->HasBodyTextL() ? store->RestoreBodyTextL(*richText) : User::Leave( KErrNotFound); TInt messageLength = richText->DocumentLength(); delete iMessageBody; iMessageBody = HBufC::NewL(messageLength); TPtr messDes = iMessageBody->Des(); TInt length = messDes.Length(); while(length < messageLength) { TPtrC desc = richText->Read(length, messageLength-length); messDes.Append(desc); length+=desc.Length(); } CleanupStack::PopAndDestroy(4); // store, text, charFormatLayer, paraFormatLayer return messDes; }EXPORT_C void CBioTestUtils::LogExtractedFieldsL(TMsvId aMessage) { // make sure we've got the right entry CMsvStore* store = NULL; if(iClientServer==EServerSide) { User::LeaveIfError(iServerEntry->SetEntry(aMessage)); if(iServerEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) User::Leave(KBspInvalidMessage); store = iServerEntry->ReadStoreL(); } else { iMsvEntry->SetEntryL(aMessage); if(iMsvEntry->Entry().iMtm.iUid != KUidMsgTypeSmartMessage.iUid) User::Leave(KBspInvalidMessage); store = iMsvEntry->ReadStoreL(); } // Extract the body text or leave false if not CleanupStack::PushL(store); // try to get our array of parsed fields RMsvReadStream in; in.OpenLC( *store, KUidMsvBIODataStream ); InternalizeL(in); CleanupStack::PopAndDestroy(); HBufC* fieldBuf = NULL; TInt length = 0; WriteComment(_L("Extracted fields")); for(TInt loop = 0; loop < iTestParsedFieldArray->Count(); loop++) { CParsedField& field = *(*iTestParsedFieldArray)[loop]; length = (field.FieldName().Length() + field.FieldValue().Length() + 1); delete fieldBuf; fieldBuf = HBufC::NewL(length); TPtr des = fieldBuf->Des(); des.Append(field.FieldName()); des.Append(KCharSpace); des.Append(field.FieldValue()); //FieldValue may be bigger than '0x100' i.e logging script //this may exeede max buffer, so we need to break it into chuncks //of 64 chars and log the chuncks in sequence. TInt desLength = des.Length(); TInt BufSize=64; if (desLength > BufSize) { TBuf<64> tempBuf; TInt count=0; while(count <= desLength) { if(desLength-count > BufSize ) tempBuf= des.Mid(count,BufSize); else tempBuf= des.Mid(count,desLength-count); WriteComment(tempBuf); count+=BufSize; } } else WriteComment(des); } delete fieldBuf; CleanupStack::PopAndDestroy(); }void CBioTestUtils::InternalizeL(RMsvReadStream& aReadStream) { if(iTestParsedFieldArray) { iTestParsedFieldArray->ResetAndDestroy(); delete iTestParsedFieldArray; iTestParsedFieldArray=NULL; } iTestParsedFieldArray = new(ELeave) CArrayPtrSeg<CParsedField>(16); CParsedField* parsedField = NULL; TInt count = aReadStream.ReadUint8L(); for (TInt i=0; i < count; i++) { parsedField = new (ELeave) CParsedField(); TRAPD(err, parsedField->InternalizeL(aReadStream)) if(err) { delete parsedField; //deletes the last allocated object, privious ones will be deleted by iParsedFieldArray->ResetAndDestroy() User::Leave(err); } iTestParsedFieldArray->AppendL(parsedField); } }EXPORT_C CArrayPtrSeg<CParsedField>& CBioTestUtils::ParsedFieldArray() { return *iTestParsedFieldArray; }